1
0
This repository has been archived on 2025-03-06. You can view files and clone it, but cannot push or open issues or pull requests.
on-restart-benchmarks/gecode/int/view-val-graph.hh
Jip J. Dekker 981be2067e Squashed 'software/gecode_on_replay/' content from commit 8051d92b9
git-subtree-dir: software/gecode_on_replay
git-subtree-split: 8051d92b9c89e49cccfbd1c201371580d7703ab4
2021-06-16 14:04:29 +10:00

331 lines
9.6 KiB
C++

/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Main authors:
* Christian Schulte <schulte@gecode.org>
* Guido Tack <tack@gecode.org>
*
* Copyright:
* Christian Schulte, 2002
* Guido Tack, 2004
*
* This file is part of Gecode, the generic constraint
* development environment:
* http://www.gecode.org
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef GECODE_INT_VIEW_VAL_GRAPH_HH
#define GECODE_INT_VIEW_VAL_GRAPH_HH
#include <gecode/int.hh>
/**
* \namespace Gecode::Int::ViewValGraph
* \brief Support classes for propagators using a view-value graph
*/
namespace Gecode { namespace Int { namespace ViewValGraph {
/**
* \brief Class for combining two pointers with a flag
*
* When one pointer is given, the other can be retrieved.
*
*/
template<class T>
class CombPtrFlag {
private:
/// Store pointer and flag
ptrdiff_t cpf;
public:
/// Initialize with pointer \a p1 and \a p2
CombPtrFlag(T* p1, T* p2);
/// Initialize with pointer \a p1 and \a p2
void init(T* p1, T* p2);
/// Return the other pointer when \a p is given
T* ptr(T* p) const;
/// Check whether flag is set
int is_set(void) const;
/// Set flag
void set(void);
/// Clear flag
void unset(void);
};
/// Bidirectional links for edges and anchors in nodes of view-value graph
class BiLink {
private:
/// Link to previous element
BiLink* _prev;
/// Link to next element
BiLink* _next;
public:
/// Initialize as empty (self referenced)
BiLink(void);
/// Return previous element
BiLink* prev(void) const;
/// Return next element
BiLink* next(void) const;
/// Set previous element to \a l
void prev(BiLink* l);
/// Set next element to \a l
void next(BiLink* l);
/// Add \a l after this element
void add(BiLink* l);
/// Unlink this element
void unlink(void);
/// Mark element (invalidates next element pointer)
void mark(void);
/// Whether element is marked
bool marked(void) const;
/// Whether element has no previous and next element
bool empty(void) const;
};
template<class View> class Edge;
/**
* \brief Base-class for nodes (both view and value nodes)
*
* Note: the obvious ill-design to have also nodes and edges
* parametric wrt View is because the right design (having template
* function members) gets miscompiled (and actually not even compiled
* with some C++ compilers). Duh!
*
*/
template<class View>
class Node : public BiLink {
public:
/// Next edge for computing strongly connected components
Edge<View>* iter;
/// Values for computing strongly connected components
unsigned int low, min, comp;
/// Initialize
Node(void);
/// Return first edge (organized by bi-links)
Edge<View>* edge_fst(void) const;
/// Return last edge (organized by bi-links)
Edge<View>* edge_lst(void) const;
/// Allocate memory from space
static void* operator new(size_t, Space&);
/// Needed for exceptions
static void operator delete(void*, size_t);
/// Needed for exceptions
static void operator delete(void*,Space&);
};
/**
* \brief Value nodes in view-value graph
*
*/
template<class View>
class ValNode : public Node<View> {
protected:
/// The value of the node
const int _val;
/// The matching edge
Edge<View>* _matching;
/// The next value node
ValNode<View>* _next_val;
public:
/// Initialize with value \a v
ValNode(int v);
/// Initialize with value \a v and successor \a n
ValNode(int v, ValNode<View>* n);
/// Return value of node
int val(void) const;
/// Set matching edge to \a m
void matching(Edge<View>* m);
/// Return matching edge (nullptr if unmatched)
Edge<View>* matching(void) const;
/// Return pointer to next value node fields
ValNode<View>** next_val_ref(void);
/// Return next value node
ValNode<View>* next_val(void) const;
/// Set next value node to \a v
void next_val(ValNode<View>* v);
};
/**
* \brief View nodes in view-value graph
*
*/
template<class View>
class ViewNode : public Node<View> {
protected:
/// The size of the view after last change
unsigned int _size;
/// The node's view
View _view;
/// The first value edge
Edge<View>* _val_edges;
public:
/// Initialize node for a non-view
ViewNode(void);
/// Initialize new node for view \a x
ViewNode(View x);
/// Return first edge of all value edges
Edge<View>* val_edges(void) const;
/// Return pointer to first edge fields of all value edges
Edge<View>** val_edges_ref(void);
/// Test whether node has a fake view
bool fake(void) const;
/// Return view
View view(void) const;
/// Update size of view after change
void update(void);
/// Return whether view has changed its size
bool changed(void) const;
/// Whether the node is matched
bool matched(void) const;
};
/**
* \brief Edges in view-value graph
*
*/
template<class View>
class Edge : public BiLink {
protected:
/// Next edge in chain of value edges
Edge<View>* _next_edge;
/// Combine source and destination node and flag
CombPtrFlag<Node<View> > sd;
public:
/// Construct new edge between \a x and \a v
Edge(ValNode<View>* v, ViewNode<View>* x);
/// Construct new edge between \a x and \a v with next edge \a n
Edge(ValNode<View>* v, ViewNode<View>* x, Edge<View>* n);
/// Return destination of edge when source \a s is given
Node<View>* dst(Node<View>* s) const;
/// Return view node when value node \a v is given
ViewNode<View>* view(ValNode<View>* v) const;
/// Return value node when view node \a x is given
ValNode<View>* val(ViewNode<View>* x) const;
/// Whether edge is used (marked or between nodes from the same scc)
bool used(Node<View>* v) const;
/// Mark node as used
void use(void);
/// Unmark node as used
void free(void);
/// Revert edge to node \a d for matching
void revert(Node<View>* d);
/// Return next edge in list of value edges
Edge<View>* next_edge(void) const;
/// Return reference to next edge in list of value edges
Edge<View>** next_edge_ref(void);
/// Return next edge in list of edges per node
Edge<View>* next(void) const;
/// Allocate memory from space
static void* operator new(size_t, Space&);
/// Needed for exceptions
static void operator delete(void*, size_t);
/// Needed for exceptions
static void operator delete(void*,Space&);
};
/// Iterates the values to be pruned from a view node
template<class View>
class IterPruneVal {
protected:
/// View node
ViewNode<View>* x;
/// Current value edge
Edge<View>* e;
public:
/// \name Constructors and initialization
//@{
/// Initialize with edges for view node \a x
IterPruneVal(ViewNode<View>* x);
//@}
/// \name Iteration control
//@{
/// Test whether iterator is still at a value or done
bool operator ()(void) const;
/// Move iterator to next value (if possible)
void operator ++(void);
//@}
/// \name Value access
//@{
/// Return current value
int val(void) const;
//@}
};
}}}
#include <gecode/int/view-val-graph/comb-ptr-flag.hpp>
#include <gecode/int/view-val-graph/bi-link.hpp>
#include <gecode/int/view-val-graph/edge.hpp>
#include <gecode/int/view-val-graph/node.hpp>
#include <gecode/int/view-val-graph/iter-prune-val.hpp>
namespace Gecode { namespace Int { namespace ViewValGraph {
/// View-value graph base class
template<class View>
class Graph {
protected:
/// Array of view nodes
ViewNode<View>** view;
/// Array of value nodes
ValNode<View>* val;
/// Number of view nodes
int n_view;
/// Number of value nodes
int n_val;
/// Marking counter
unsigned int count;
/// Stack used during matching
typedef Support::StaticStack<ViewNode<View>*,Region> ViewNodeStack;
/// Initialize the edges for the view node \a x
void init(Space& home, ViewNode<View>* x);
/// Find a matching for node \a x
bool match(ViewNodeStack& m, ViewNode<View>* x);
/// Compute the strongly connected components
void scc(void);
public:
/// Construct graph as not yet initialized
Graph(void);
/// Test whether graph has been initialized
operator bool(void) const;
/// Purge graph if necessary (reset information to avoid overflow)
void purge(void);
};
}}}
#include <gecode/int/view-val-graph/graph.hpp>
#endif
// STATISTICS: int-prop