1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344
|
/**************************************************************************
* *
* Regina - A Normal Surface Theory Calculator *
* Computational Engine *
* *
* Copyright (c) 1999-2011, Ben Burton *
* For further details contact Ben Burton (bab@debian.org). *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 2 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 General Public *
* License along with this program; if not, write to the Free *
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
**************************************************************************/
/* end stub */
/*! \file subcomplex/nsatblockstarter.h
* \brief Provides a hard-coded list of saturated blocks to use as starting
* points for recognising larger Seifert fibred spaces.
*/
#ifndef __NSATBLOCKSTARTER_H
#ifndef __DOXYGEN
#define __NSATBLOCKSTARTER_H
#endif
#include "regina-core.h"
#include "subcomplex/nsatblock.h"
#include "triangulation/ntriangulation.h"
#include "utilities/nlistoncall.h"
namespace regina {
/**
* \weakgroup subcomplex
* @{
*/
/**
* Contains a triangulation of a saturated block along with the
* accompanying saturated block description. Different objects of this
* class will correspond to different types of saturated block.
*
* This is a support class for NSatBlockStarterSet, and as such it is a
* read-only class to the rest of the world.
*
* This class is well-suited for subcomplex testing: if the
* triangulation here is found to be a subcomplex of some larger
* triangulation (see NTriangulation::isContainedIn()), then the
* corresponding isomorphism can be used to copy this block structure
* and transform it to describe the corresponding block in the larger
* triangulation.
*
* As such, one of the core uses of this class is as a starting point
* for identifying regions within triangulations that are formed by
* joining saturated blocks together along their boundary annuli. See
* the routines NSatBlockStarterSearcher::findStarterBlocks() and
* NSatRegion::expand() for implementations of this.
*
* \ifacespython Not present.
*/
class REGINA_API NSatBlockStarter : regina::boost::noncopyable {
private:
NTriangulation triangulation_;
/**< The triangulation of the saturated block. */
NSatBlock* block_;
/**< Structural details of the saturated block. */
public:
/**
* Destroys both the internal triangulation and block structure.
*/
~NSatBlockStarter();
/**
* Returns a reference to the triangulation of the saturated
* block.
*
* @return the block triangulation.
*/
const NTriangulation& triangulation() const;
/**
* Returns details that describe the structure of the saturated
* block.
*
* @return the block structure.
*/
const NSatBlock* block() const;
private:
/**
* Creates a new starter block. The triangulation will be empty
* and the block pointer set to null.
*
* The triangulation must be fleshed out and the block structure
* created before this object can be used.
*/
NSatBlockStarter();
friend class NSatBlockStarterSet;
};
/**
* Represents a set of starter blocks that can be used for identifying
* triangulations of Seifert fibred spaces.
*
* This class provides a list of saturated blocks that can be used as
* starting points for recognising triangulations; see the
* NSatBlockStarter class notes for details.
*
* More importantly, this list is global and hard-coded. The only
* access to the list is through the static routines begin() and end().
*
* Creating the list of starter blocks is expensive, and so this is not
* done until the first time that begin() is called. This way, if the list
* is never used then the work is never done. As a consequence however,
* you must be sure to call begin() before calling end() (which is the
* usual way in which iterator loops are structured in code).
*
* Be aware that this list makes no claims to be exhaustive; it is
* expected to grow as future versions of Regina are released.
*
* \ifacespython Not present.
*/
class REGINA_API NSatBlockStarterSet : private NListOnCall<NSatBlockStarter> {
public:
/**
* An iterator over the starter blocks in this list. This operates
* as a forward iterator in a manner consistent with the standard C++
* library.
*/
typedef NListOnCall<NSatBlockStarter>::iterator iterator;
private:
static const NSatBlockStarterSet blocks;
/**< The hard-coded list of starter blocks. */
public:
/**
* Returns an iterator pointing to the first block in the
* hard-coded list.
*
* The very first time this routine is called, the list will be
* filled with items (and as such the call will be expensive).
* Every subsequent call will be very cheap.
*
* @return an iterator pointing to the first starter block.
*/
static iterator begin();
/**
* Returns an iterator pointing past the end of the hard-coded list
* (i.e., just after the last item).
*
* \pre The begin() routine has been called at least once.
*
* @return a past-the-end iterator.
*/
static iterator end();
protected:
void initialise();
private:
/**
* Creates a new list of starter blocks. This routine is
* private since the only list that should exist is the global
* hard-coded list.
*/
NSatBlockStarterSet();
};
/**
* A helper class for locating and using starter blocks within a
* triangulation.
*
* This class provides a means for searching for each starter
* block in the global hard-coded NSatBlockStarterSet within a
* given triangulation. More specifically, given some triangulation \a t,
* this class can locate every isomorphic embedding of every starter
* block in the global NSatBlockStarterSet as a subcomplex of \a t (see
* NTriangulation::isContainedIn() for what is meant by "isomorphic
* embedding").
*
* The routine findStarterBlocks() runs the search. Each time an
* isomorphic embedding of a starter block is discovered within the
* given triangulation, the pure virtual routine useStarterBlock() will
* be called. The block that is passed to useStarterBlock() will be a
* new block that refers to the particular embedding of the starter block
* within the given triangulation (as opposed to the original block
* structure referring to the prebuilt triangulation in NSatBlockStarter).
*
* For each situation that requires searching for starter blocks, a
* subclass of NSatBlockStarterSearcher will be required. This subclass
* should override useStarterBlock() to perform whatever action is
* necessary.
*
* Instead of locating all isomorphic embeddings of all starter blocks
* in the global set, the search can be made to finish early once
* certain conditions are met. This is done by implementing
* useStarterBlock() to return \c false when the search should quit.
*
* \ifacespython Not present.
*/
class REGINA_API NSatBlockStarterSearcher {
protected:
NSatBlock::TetList usedTets;
/**< Keeps track of which tetrahedra have used by the
current embedding of the current starter block.
See useStarterBlock() for further details. */
public:
/**
* Destroys this object and its internal structures.
*/
virtual ~NSatBlockStarterSearcher();
/**
* Runs a search for every isomorphic embedding of every
* starter block from the global NSatBlockStarterSet within the
* given triangulation. Each time an embedding is discovered,
* the pure virtual routine useStarterBlock() will be called.
*
* See the NSatBlockStarterSearcher class notes for greater
* detail on what this search does and how it runs.
*
* For subclasses that make use of the \a usedTets data member,
* it is worth noting that this routine empties the \a usedTets
* list on both entry and exit, as well as every time that
* useStarterBlock() returns after each new embedding is found.
*
* @param tri the triangulation in which to search for starter
* blocks.
*/
void findStarterBlocks(NTriangulation* tri);
protected:
/**
* Used by subclasses to process each starter block embedding that
* is found.
*
* Suppose that the main search routine findStarterBlocks() has
* been called with some triangulation \a t. Each time it
* locates an isomorphic embedding of a starter block within \a t,
* it will call useStarterBlock(). Subclasses of
* NSatBlockStarterSearcher should therefore override
* useStarterBlock() to process each embedding in whatever way
* is appropriate for the problem at hand.
*
* The block passed in the argument \a starter is a newly
* created structure describing the starter block as it appears
* within the triangulation \a t. Thus different embeddings of
* the same starter block within \a t will pass different
* \a starter arguments to this routine.
* It is the responsibility of useStarterBlock() to either
* destroy the new block \a starter or pass ownership of it
* elsewhere.
*
* When this routine is called, the data member \a usedTets
* will contain a list of all tetrahedra from the triangulation
* \a t that appear within the relevant starter block embedding.
* The reimplementation of useStarterBlock() may modify this list
* as it pleases, since the main search routine will empty the
* list anyway when useStarterBlock() returns. One possible use
* for the \a usedTets data member is for passing to
* NSatBlock::isBlock() or NSatRegion::expand() as the list of
* tetrahedra to avoid in further searches.
*
* This routine must return a boolean; this allows subclasses to
* immediately terminate the main search once they have found
* whatever it is they were looking for. A return value of
* \c true signifies that the search should continue as normal,
* whereas a return value of \c false signifies that the search
* should end immediately (specifically, that findStarterBlocks()
* should clean up and return before all remaining embeddings of all
* starter blocks have been found).
*
* \warning Subclasses must remember to either destroy or claim
* ownership of the newly created block \a starter.
*
* @param starter a newly created structure describing the
* starter block as it appears within the larger triangulation
* currently under examination.
* @return \c true if the search for embeddings of starter blocks
* should continue, or \c false if the search should stop immediately.
*/
virtual bool useStarterBlock(NSatBlock* starter) = 0;
};
/*@}*/
// Inline functions for NSatBlockStarter
inline NSatBlockStarter::NSatBlockStarter() : block_(0) {
}
inline NSatBlockStarter::~NSatBlockStarter() {
if (block_)
delete block_;
}
inline const NTriangulation& NSatBlockStarter::triangulation() const {
return triangulation_;
}
inline const NSatBlock* NSatBlockStarter::block() const {
return block_;
}
// Inline functions for NSatBlockStarterSet
inline NSatBlockStarterSet::NSatBlockStarterSet() {
}
inline NSatBlockStarterSet::iterator NSatBlockStarterSet::begin() {
return blocks.NListOnCall<NSatBlockStarter>::begin();
}
inline NSatBlockStarterSet::iterator NSatBlockStarterSet::end() {
return blocks.NListOnCall<NSatBlockStarter>::end();
}
// Inline functions for NSatBlockStarterSearcher
inline NSatBlockStarterSearcher::~NSatBlockStarterSearcher() {
}
} // namespace regina
#endif
|