home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
tlx501.zip
/
SRC
/
VARIABLE.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-08
|
9KB
|
271 lines
/****************************************************************************
$Id: variable.cpp 501.0 1995/03/07 12:26:26 RON Exp $
Copyright (c) 1991-95 Tarma Software Research. All rights reserved.
Project: Tarma Library for C++ V5.0
Author: Ron van der Wal
Implementation of the TLVariable class. This class is the abstract base
class for all variables in the CSP framework.
$Log: variable.cpp $
Revision 501.0 1995/03/07 12:26:26 RON
Updated for TLX 5.01
Revision 1.16 1995/01/31 16:30:32 RON
Update for release 012
Added partial support for SunPro C++ compiler
Revision 1.15 1995/01/13 15:35:31 ron
Added activation/deactivation count for debugging purposes
Revision 1.14 1995/01/06 15:58:41 ron
Corrected Revision keyword
Revision 1.13 1995/01/05 15:31:25 ron
Naming changes
Revision 1.12 1994/11/16 15:45:42 ron
Added module info; rearranged #include directives
Revision 1.11 1994/10/10 16:57:12 ron
Changed to <tlx\solve\csp.h>
Revision 1.10 1994/10/05 18:45:39 ron
Implemented support for constraint activation/deactivation
Revision 1.9 1994/09/28 14:47:19 ron
Removed Macintosh-style #include references
Revision 1.8 1994/09/28 14:23:36 ron
Adapted to change from TLVarDomainMonitor to TLDomainMonitor
Revision 1.7 1994/09/27 20:23:24 ron
Changed path separator from / to \
Revision 1.6 1994/09/26 15:50:36 ron
Adapted to changes in constraint check counting
Revision 1.5 1994/09/13 10:16:07 ron
Added code to remember the first constraint that fails during
propagation of changes.
Revision 1.4 1994/09/07 15:45:02 ron
Small formatting changes
Revision 1.3 1994/09/06 20:25:59 ron
Renamed RegisterDomain() to SaveDomain()
Revision 1.2 1994/09/06 14:08:16 ron
Implemented new functions due to changes in the algorithms
Revision 1.1 1994/08/16 18:13:21 ron
Initial revision
****************************************************************************/
#include <tlx\501\_build.h>
TLX_MODULE_INFO("$Revision: 501.0 $");
#include <tlx\501\solve\csp.h>
/*---------------------------------------------------------------------------
Template instantiations
---------------------------------------------------------------------------*/
#ifdef THINK_CPLUS
#include "ptrseq.cpp"
#pragma template TLPtrSeq<TLConstraint>
#else
#include <tlx\501\template\ptrseq.cpp>
#endif
/*---------------------------------------------------------------------------
Static class variables
---------------------------------------------------------------------------*/
TLPropagator * TLVariable::sPropagator = 0;
TLDomainMonitor * TLVariable::sDomainMonitor = 0;
/*-------------------------------------------------------------------------*/
TLVariable::TLVariable(const char *nm)
/* Constructor. Stores a duplicate of the variable's name.
---------------------------------------------------------------------------*/
: mName(0), mConstraints(10, 10)
{
mIsPropagating = false;
mConIndex = 0;
mProblem = 0;
#ifdef _TLXDBG
mDeactiveCount = 0;
#endif
SetName(nm);
}
/*-------------------------------------------------------------------------*/
TLVariable::~TLVariable()
/* Destructor. Discards name storage.
---------------------------------------------------------------------------*/
{
delete [] mName;
}
/*-------------------------------------------------------------------------*/
void TLVariable::ActivateConstraints()
/* Activates all constraints attached to the variable.
---------------------------------------------------------------------------*/
{
#ifdef _TLXDBG
if (--mDeactiveCount < 0)
{
TLX_TRACE_WARN(TLX, ("%s: Too many constraint activations",
GetName()));
mDeactiveCount = 0;
}
#endif
for (index_t i = mConstraints.Mini(); i <= mConstraints.Maxi(); i++)
mConstraints.PeekAt(i)->Activate();
}
/*-------------------------------------------------------------------------*/
void TLVariable::AddConstraint(TLConstraint *con)
/* Adds a constraint to the list of constraints whose revision depends on
changes in the current variable. The constraint will only be added
if it does not yet appear in the list.
---------------------------------------------------------------------------*/
{
TLX_ASSERT_PTR(con);
if (!mConstraints.Contains(con))
mConstraints.Append(con);
}
/*-------------------------------------------------------------------------*/
void TLVariable::DeactivateConstraints()
/* Deactivates all constraints attached to the variable.
---------------------------------------------------------------------------*/
{
#ifdef _TLXDBG
if (mDeactiveCount < INT_MAX)
++mDeactiveCount;
else
TLX_TRACE_WARN(TLX, ("%s: Maximum number of deactivations exceeded",
GetName()));
#endif
for (index_t i = mConstraints.Mini(); i <= mConstraints.Maxi(); i++)
mConstraints.PeekAt(i)->Deactivate();
}
/*-------------------------------------------------------------------------*/
bool TLVariable::PropagateChanges()
/* Propagates changes made to the current variable by calling the Propagate()
procedure for all constraints attached to the variable. To prevent
recursive calls from eating up runtime stack space and performing
unnecessary work, we check for recursive calls. If we find one, we
reset the current constraint iterator rather than starting a new
propagation.
---------------------------------------------------------------------------*/
{
if (mIsPropagating)
{
// Already propagating. Do not restart propagating right now; just
// reset the constraint iteration index and drop out. When the
// recursion unwinds back to the original call to this function,
// it will simply re-evaluate the constraints involved.
//
// We set the index to Mini() - 1, because the constraint evaluation
// loop below will increment the index before doing anything else.
mConIndex = mConstraints.Mini() - 1;
}
else
{
// Propagate changes through all constraints
//
// TODO: make the following a lock. In the current version,
// the mIsPropagating flag is never reset if the routine is left
// as the result of stack unwinding during exception handling.
mIsPropagating = true;
for (mConIndex = mConstraints.Mini();
mConIndex <= mConstraints.Maxi(); mConIndex++)
{
// The following PropagateCond() call may lead (eventually) to
// a recursive call to this function.
if (!mConstraints.PeekAt(mConIndex)->PropagateCond(this))
{
// Dead end: stop propagation and return false. The
// constraint that failed is registered with the
// propagator (if any).
if (sPropagator)
sPropagator->SetFailedConstraint(mConstraints.PeekAt(
mConIndex));
mIsPropagating = false;
return false;
}
}
// If we get here, all constraints were revised without problems.
mIsPropagating = false;
}
return true;
}
/*-------------------------------------------------------------------------*/
void TLVariable::RegisterChanges(DomChanges)
/* Called to register changes to the variable. If there is currently
an active propagator, it will be informed of the changes; else our
own PropagateChanges() will be invoked (which will guard against
uncontrolled recursion).
---------------------------------------------------------------------------*/
{
if (sPropagator)
sPropagator->RegisterChanges(this);
else
PropagateChanges();
}
/*-------------------------------------------------------------------------*/
void TLVariable::RemoveConstraint(TLConstraint *con)
/* Removes a constraint from the list of dependent constraints.
---------------------------------------------------------------------------*/
{
TLX_ASSERT_PTR(con);
mConstraints.Remove(con);
}
/*-------------------------------------------------------------------------*/
void TLVariable::SaveDomain()
/* Called to register the current domain of the variable, presumably
because it will be modified shortly. If there is an active domain
monitor, it will inform that monitor of the request; this may cause
the monitor to call back to our CopyDomain() function.
---------------------------------------------------------------------------*/
{
if (sDomainMonitor)
sDomainMonitor->CaptureDomain(this);
}
/*-------------------------------------------------------------------------*/
void TLVariable::SetName(const char *aName)
/* Changes the name of the variable, discarding the previous one.
---------------------------------------------------------------------------*/
{
delete [] mName;
mName = aName ? tlStrDup(aName) : 0;
}