Semantic Engine Core C++ API

By Gabriel Schine

This file describes the Semantic Engine core API. All the main functionality of the Semantic Engine is described here, supplemented by the documentation in subgraph.hpp, which describes the sub-graph capabilities of the Semantic Engine.


1. Semantic Engine Core API
     1.1. Graph-Based Indexing
     1.2. Policy-Based Functionality
     1.3. Base class SEGraph
               1.3.1. Constructor
               1.3.2. Accessing Properties
               1.3.3. Weighting the Edges
               1.3.4. Structure Modification Member Functions
                    1.3.4.1. Pruning Helper Methods
     1.4. Related Non-member Functions
               1.4.1. add_vertex
               1.4.2. add_edge
               1.4.3. add_or_strengthen_edge
               1.4.4. remove_edge
               1.4.5. remove_out_edge_if
               1.4.6. remove_in_edge_if
               1.4.7. remove_edge_if
               1.4.8. clear_vertex
               1.4.9. clear_out_edges
               1.4.10. clear_in_edges
               1.4.11. remove_vertex
               1.4.12. merge_vertices
               1.4.13. either_edge
               1.4.14. ostream output
     1.5. Managing Indices
     1.6. Using Smart Pointers
     1.7. The File: semantic.hpp


1. Semantic Engine Core API

This file describes the Semantic Engine core API. All the main functionality of the Semantic Engine is described here, supplemented by the documentation in subgraph.hpp, which describes the sub-graph capabilities of the Semantic Engine.


1.1. Graph-Based Indexing

The Semantic Engine stores indices in a graph. A graph is a number of nodes and edges, with edges "connecting" two nodes together. The graph is bipartite in nature, directed and cannot have parallel edges. Any tools using the text-indexing features of the Semantic Engine can assume that a document node will always be connected to a term node, and vice versa.

Heavy usage of the BOOST C++ Libraries (http://boost.org/) at the core of the Semantic Engine API offers stability and a common interface between BOOST libraries and the libraries of the Semantic Engine.

The Semantic Engine API supplies extensions to the BGL (BOOST Graph Library). All functions are overloaded in the boost::* namespace. In this way, coders familiar with the BOOST API will easily transition into the Semantic API.


1.2. Policy-Based Functionality

Much of the power of the Semantic Engine comes from the leverage of policy-based programming. Policies are template arguments to the Semantic Engine base class (SEGraph) which alter core functionality. For SEGraph, the Storage Policy is chosen by passing a Storage Policy Selector type to the class. Storage Policies determine how an index will persist across program runs. A number of Storage Policies are included (see the files under storage/) and others can be easily written (see storage/concept.hpp for details).


1.3. Base class SEGraph

This class is at the core of the Semantic Engine. Its construction is a little complicated, so if you're trying to understand it, please try to read through this entire section.

To access NoStoragePolicy and the se_graph_traits below we need to include the appropriate files:

1. includes+={
#include <semantic/config.hpp>
#include <semantic/storage/none.hpp>
#include <semantic/properties.hpp>
}
This macro is defined in definitions 1 and 9.
This macro is invoked in definition 31.

2. SEGraph={
template <
    class StoragePolicySelector = NoStoragePolicy,
    class SEBase = StoragePolicy<
        StoragePolicySelector,
        typename se_graph_traits<StoragePolicySelector>::base_graph_type >
    > class SEGraph : public SEBase
{
    typedef SEGraph<StoragePolicySelector, SEBase> self_type;
    typedef storage_traits<StoragePolicySelector> storage_traits;
    typedef se_graph_traits<StoragePolicySelector> se_traits;

    public:
        
SEGraph public scope
};
}
This macro is invoked in definition 31.

The SEGraph is built such that every class up the inheritance tree can be customized at type definition time. The class's parent type: SEBase is defined as the StoragePolicy template class. StoragePolicy classes take two template arguments, the first being the StoragePolicySelector. This type is an empty struct defined by a Storage Policy, coupled with a definition of StoragePolicy<StoragePolicySelector, SEBase>. The struct se_graph_traits lives in the semantic::* namespace and is defined in properties.hpp. se_graph_traits<StoragePolicySelector>::base_graph_type is a BOOST graph type. The SEBase template argument should never be altered. It was left open for future development.

The following typedefs are made publicly available by the SEGraph class.

3. SEGraph public scope+={
typedef SEBase base_type;
typedef typename se_traits::base_graph_type base_graph_type;
typedef StoragePolicySelector storage_policy_selector;
typedef base_type storage_policy_type;
}
This macro is defined in definitions 3, 4, 5, 6, 7, 8, 10, 11, 12 and 29.
This macro is invoked in definition 2.


1.3.1. Constructor

The constructor is simple, and accepts only the name of the collection to which this graph should be tied. All operations performed on this graph will only affect the collection named in the constructor. For this reason, if multiple operations on multiple collections is desired, you must create multiple graph objects!

4. SEGraph public scope+={
SEGraph() { SEGraph(""); }
explicit SEGraph(string name)
    : base_type(), __refcount(0)
{
    storage_policy_type::set_mirror_changes_to_storage(false);
    set_property(*this, graph_name, name);
    set_property(*this, graph_energy_hits, 1);
}
}
This macro is defined in definitions 3, 4, 5, 6, 7, 8, 10, 11, 12 and 29.
This macro is invoked in definition 2.


1.3.2. Accessing Properties

In order to access vertex and edge properties (see se_graph_traits<StoragePolicySelector>::vertex_properties_type and se_graph_traits<StoragePolicySelector>::edge_properties_type), we need to create accessor methods to get to them quickly. These methods exactly mirror those available in the BGL.

5. SEGraph public scope+={
typename storage_traits::vertex_properties_type &
operator [] (typename se_traits::vertex_descriptor v) { return (get(vertex_bundle, *this))[v]; }
const typename storage_traits::vertex_properties_type &
operator [] (typename se_traits::vertex_descriptor v) const { return (get(vertex_bundle, *this))[v]; }
typename storage_traits::edge_properties_type &
operator [] (typename se_traits::edge_descriptor e) { return (get(edge_bundle, *this))[e]; }
const typename storage_traits::edge_properties_type &
operator [] (typename se_traits::edge_descriptor e) const { return (get(edge_bundle, *this))[e]; }
}
This macro is defined in definitions 3, 4, 5, 6, 7, 8, 10, 11, 12 and 29.
This macro is invoked in definition 2.

And this one allows you to get the name of the collection to which this graph is tied.

6. SEGraph public scope+={
std::string collection() const {
    return get_property(*this, graph_name);
}
}
This macro is defined in definitions 3, 4, 5, 6, 7, 8, 10, 11, 12 and 29.
This macro is invoked in definition 2.


1.3.3. Weighting the Edges

The following method is supplied as a convenience method. The WeightingPolicy defines the algorithm to use to apply weights to the supplied WeightMap.

More information on Weighting Policies can be found in the weighting/ subdirectory.

The WeightMap must be a BOOST property map keyed by edge.

7. SEGraph public scope+={
template <class WeightingPolicy, class WeightMap>
void populate_weight_map(WeightingPolicy weighting, WeightMap w) {
    typedef typename WeightingPolicy::weight_type weight_type;
    typedef typename se_traits::edge_descriptor Edge;
    typedef typename se_traits::vertex_iterator iterator;

    // make sure we were passed the right kind of WeightMap
    function_requires< WritablePropertyMapConcept<WeightMap, Edge> >();
    BOOST_STATIC_ASSERT((boost::is_same<typename boost::property_traits<WeightMap>::value_type, weight_type>::value));

    // go through all the vertices and apply our weighting algorithm
    iterator vi, vi_end;
    for(boost::tie(vi, vi_end) = vertices(*this); vi != vi_end; ++vi) {
        weighting.apply_weights(*vi, *this, w);
    }
}
}
This macro is defined in definitions 3, 4, 5, 6, 7, 8, 10, 11, 12 and 29.
This macro is invoked in definition 2.


1.3.4. Structure Modification Member Functions

8. SEGraph public scope+={
void clear() {
    storage_policy_type::will_clear();
    base_type::clear();
    storage_policy_type::did_clear();
}
}
This macro is defined in definitions 3, 4, 5, 6, 7, 8, 10, 11, 12 and 29.
This macro is invoked in definition 2.

clear() overrides the function of the same name in the BGL. Here the Storage Policy gets a chance to perform any operations before and after the actual clearing of the in-memory graph.


1.3.4.1. Pruning Helper Methods

The following methods are helpers that make it easy to apply pruning operations to a graph, its vertices or edges. See the file pruning.hpp for example (and useful!) pruning methods.

These methods make heavy use of the BOOST graph iteration macros:

9. includes+={
#include <boost/graph/iteration_macros.hpp>
}
This macro is defined in definitions 1 and 9.
This macro is invoked in definition 31.

10. SEGraph public scope+={
template <class Functor>
void apply_to_graph(Functor f) {
    f(*this);
}
}
This macro is defined in definitions 3, 4, 5, 6, 7, 8, 10, 11, 12 and 29.
This macro is invoked in definition 2.

For apply_to_graph(), Functor must have an operator () method defined and templated on a single parameter (the Graph type).

11. SEGraph public scope+={
template <class Functor>
void apply_to_all_vertices(Functor f) {
    BGL_FORALL_VERTICES_T(v, (*this), base_graph_type) f(v, *this);
}
}
This macro is defined in definitions 3, 4, 5, 6, 7, 8, 10, 11, 12 and 29.
This macro is invoked in definition 2.

For apply_to_all_vertices(), Functor must have an operator () method defined and templated on at least the Graph (second) parameter. The first will be a se_graph_traits<Graph>::vertex_descriptor, and can be templated out of convenience if desired.

12. SEGraph public scope+={
template <class Functor>
void apply_to_all_edges(Functor f) {
    BGL_FORALL_EDGES_T(e, (*this), base_graph_type) f(e, *this);
}
}
This macro is defined in definitions 3, 4, 5, 6, 7, 8, 10, 11, 12 and 29.
This macro is invoked in definition 2.

For apply_to_all_edges(), Functor must have an operator () method defined and be templated on at least the second parameter. The first will be a se_graph_traits<Graph>::edge_descriptor and can be templated out of convenience.


1.4. Related Non-member Functions

Like in the BGL, there are a host of non-member functions that act on the SEGraph class. The names and interfaces are taken directloy frmo the BGL. Some functions that can be called safely from the BGL cannot be used with SEGraph. Those functions will throw an exception if called.

All functions that can be called on a BOOST graph can also be called on an SEGraph.


1.4.1. add_vertex

add_vertex will add a vertex to the graph and return the vertex_descriptor. You must supply a vertex_properties_type struct to the function. (see se_graph_traits<Graph>::vertex_properties_type)

Before adding, it will ask the Storage Policy if it should proceed. The Storage Policy might say no if, for example, a vertex with similar properties already exists, it might just update the properties already in the graph and avoid adding a new vertex.

After adding, it will tell the Storage Policy that a new vertex was just added.

13. non-member functions+={
template <class StoragePolicySelector, class SEBase>
inline typename se_graph_traits<StoragePolicySelector>::vertex_descriptor
add_vertex(const typename storage_traits<StoragePolicySelector>::vertex_properties_type &p, SEGraph<StoragePolicySelector, SEBase> &g)
{
    typedef typename se_graph_traits<StoragePolicySelector>::base_graph_type base_type;
    typedef typename graph_traits<base_type>::vertex_descriptor Vertex;
    typedef typename storage_traits<StoragePolicySelector>::vertex_properties_type vertex_properties_type;

    base_type& base_g = static_cast<base_type&>(g);

    Vertex v;
    bool should_add;

    boost::tie(should_add, v) = g.will_add_vertex(p);
    // should we add this vertex?
    if (should_add) {
        v = boost::add_vertex(p, base_g);
        g.did_add_vertex(v, p);
    }

    return v;
}

// THIS FUNCTION SHOULD NOT BE CALLED! USE add_vertex(properties, graph) INSTEAD
template <class StoragePolicySelector, class SEBase>
inline void
add_vertex(SEGraph<StoragePolicySelector, SEBase> &g)
{
    struct DoNotUseThisMethodException {};
    throw DoNotUseThisMethodException();
}
}
This macro is defined in definitions 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 and 25.
This macro is invoked in definition 31.


1.4.2. add_edge

add_edge will add an edge to the graph between two vertices. A set of edge_properties_type will be attached to the edge. Like in add_vertex, the Storage Policy will be asked if the edge should be added or not. A std::pair<edge_descriptor,bool> will be returned. If the bool is false, it means that the edge was not added due to there already being an edge between those vertices, or the Storage Policy denying edge addition.

The Storage Policy will be notified of edge addition after the fact, as well.

14. non-member functions+={
template <class StoragePolicySelector, class SEBase>
inline std::pair<typename se_graph_traits<StoragePolicySelector>::edge_descriptor, bool>
add_edge(
    typename se_graph_traits<StoragePolicySelector>::vertex_descriptor u,
    typename se_graph_traits<StoragePolicySelector>::vertex_descriptor v,
    const typename storage_traits<StoragePolicySelector>::edge_properties_type &p,
    SEGraph<StoragePolicySelector, SEBase> &g)
{
    typedef se_graph_traits<StoragePolicySelector> graph_traits;
    typedef typename graph_traits::vertex_descriptor Vertex;
    typedef typename graph_traits::edge_descriptor Edge;
    typedef typename graph_traits::base_graph_type base_type;

    base_type& base_g = static_cast<base_type&>(g);
    std::pair<Edge, bool> edge_result;

    if (g.will_add_edge(u, v, p)) {
        edge_result = boost::add_edge(u, v, p, base_g);
        // if it already existed, update the properties
        if (edge_result.second == false) {
            g[edge_result.first] = p;
        }

        g.did_add_edge(edge_result.first, edge_result.second, u, v, p);
    } else {
        edge_result = std::make_pair(Edge(), false);
    }

    return edge_result;
}

// THIS FUNCTION SHOULD NOT BE CALLED! USE add_edge(vertex, vertex, properties, graph) INSTEAD
template <class StoragePolicySelector, class SEBase>
inline std::pair<typename se_graph_traits<StoragePolicySelector>::edge_descriptor, bool>
add_edge(
    typename se_graph_traits<StoragePolicySelector>::vertex_descriptor u,
    typename se_graph_traits<StoragePolicySelector>::vertex_descriptor v,
    SEGraph<StoragePolicySelector, SEBase> &g)
{
    struct DoNotUseThisMethodException {};
    throw DoNotUseThisMethodException();
}
}
This macro is defined in definitions 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 and 25.
This macro is invoked in definition 31.


1.4.3. add_or_strengthen_edge

This function is identical to add_edge, except that if the edge already exists, instead of updating the properties, the property's strength member is increased by the value in the new property's field.

15. non-member functions+={
template <class StoragePolicySelector, class SEBase>
inline std::pair<typename se_graph_traits<StoragePolicySelector>::edge_descriptor, bool>
add_or_strengthen_edge(
    typename se_graph_traits<StoragePolicySelector>::vertex_descriptor u,
    typename se_graph_traits<StoragePolicySelector>::vertex_descriptor v,
    const typename storage_traits<StoragePolicySelector>::edge_properties_type &p,
    SEGraph<StoragePolicySelector, SEBase> &g)
{
    typedef se_graph_traits<StoragePolicySelector> graph_traits;
    typedef typename graph_traits::vertex_descriptor Vertex;
    typedef typename graph_traits::edge_descriptor Edge;
    typedef typename graph_traits::base_graph_type base_type;

    base_type& base_g = static_cast<base_type&>(g);
    std::pair<Edge, bool> edge_result;

    if (g.will_add_edge(u, v, p)) {
        edge_result = boost::add_edge(u, v, p, base_g);
        // if it already exists, strengthen the edge
        if (edge_result.second == false) {
            typename graph_traits::edge_properties_type old_p = g[edge_result.first];
            g[edge_result.first] = p;
            g[edge_result.first].strength += old_p.strength;
        }

        g.did_add_edge(edge_result.first, edge_result.second, u, v, g[edge_result.first]);
    } else {
        edge_result = std::make_pair(Edge(), false);
    }

    return edge_result;
}
}
This macro is defined in definitions 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 and 25.
This macro is invoked in definition 31.


1.4.4. remove_edge

remove_edge has three invokations: by edge_descriptor, by two vertex_descriptors, or by out_edge_iterator. All are functionally equivalent.

The Storage Policy will be told of edge removal before and after the fact.

16. non-member functions+={
template <class StoragePolicySelector, class SEBase>
inline void
remove_edge(
    typename se_graph_traits<StoragePolicySelector>::vertex_descriptor u,
    typename se_graph_traits<StoragePolicySelector>::vertex_descriptor v,
    SEGraph<StoragePolicySelector, SEBase> &g)
{
    typedef se_graph_traits<StoragePolicySelector> graph_traits;
    typedef typename graph_traits::edge_descriptor Edge;
    typedef typename graph_traits::base_graph_type base_type;

    base_type& base_g = static_cast<base_type&>(g);

    g.will_remove_edge(u, v);
    boost::remove_edge(u, v, base_g);
    g.did_remove_edge(u, v);
}

template <class StoragePolicySelector, class SEBase>
inline void
remove_edge(
    typename se_graph_traits<StoragePolicySelector>::edge_descriptor e,
    SEGraph<StoragePolicySelector, SEBase> &g)
{
    typedef se_graph_traits<StoragePolicySelector> graph_traits;
    typedef typename graph_traits::vertex_descriptor Vertex;
    typedef typename graph_traits::edge_descriptor Edge;
    typedef typename graph_traits::base_graph_type base_type;

    base_type& base_g = static_cast<base_type&>(g);

    Vertex u,v;
    u = boost::source(e, base_g);
    v = boost::target(e, base_g);

    g.will_remove_edge(u, v);
    boost::remove_edge(e, base_g);
    g.did_remove_edge(u, v);
}

template <class StoragePolicySelector, class SEBase>
inline void
remove_edge(
    typename se_graph_traits<StoragePolicySelector>::out_edge_iterator i,
    SEGraph<StoragePolicySelector, SEBase>& g)
{
    typedef se_graph_traits<StoragePolicySelector> graph_traits;
    typedef typename graph_traits::vertex_descriptor Vertex;
    typedef typename graph_traits::edge_descriptor Edge;
    typedef typename graph_traits::base_graph_type base_type;

    Edge e = *i;
    base_type& base_g = static_cast<base_type&>(g);

    Vertex u,v;
    u = boost::source(e, base_g);
    v = boost::target(e, base_g);

    g.will_remove_edge(u, v);
    boost::remove_edge(i, base_g);
    g.did_remove_edge(u, v);
}
}
This macro is defined in definitions 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 and 25.
This macro is invoked in definition 31.


1.4.5. remove_out_edge_if

remove_out_edge_if takes a vertex and a predicate. It iterates over the out edges of the vertex and removes any of them if Predicate(edge) resolves to true. Again, the Storage Policy will be told before and after each edge removal.

17. non-member functions+={
template <class StoragePolicySelector, class SEBase, class Predicate>
inline void
remove_out_edge_if(
    typename se_graph_traits<StoragePolicySelector>::vertex_descriptor u,
    Predicate predicate,
    SEGraph<StoragePolicySelector, SEBase> &g)
{
    typedef se_graph_traits<StoragePolicySelector> graph_traits;
    typedef typename graph_traits::vertex_descriptor Vertex;
    typedef typename graph_traits::edge_descriptor Edge;
    typedef typename graph_traits::base_graph_type base_type;
    typedef typename graph_traits::out_edge_iterator iterator;

    base_type& base_g = static_cast<base_type&>(g);

    std::vector<Edge> to_remove;
    iterator ei, ei_end;
    for(boost::tie(ei, ei_end) = boost::out_edges(u, base_g); ei != ei_end; ++ei) {
        if (predicate(*ei)) to_remove.push_back(*ei);
    }

    for(typename graph_traits::edges_size_type i = 0; i < to_remove.size(); i++) {
        Vertex v;
        v = boost::target(to_remove[i], base_g);
        g.will_remove_edge(u, v);
        boost::remove_edge(to_remove[i], base_g);
        g.did_remove_edge(u, v);
    }
}
}
This macro is defined in definitions 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 and 25.
This macro is invoked in definition 31.


1.4.6. remove_in_edge_if

This method is overloaded from the boost such that it will be impossible to call on an SEGraph. Since our graphs are directed, the concept of "in edges" doesn't really exist.

18. non-member functions+={
template <class StoragePolicySelector, class SEBase, class Predicate>
inline void
remove_in_edge_if(
    typename se_graph_traits<StoragePolicySelector>::vertex_descriptor,
    Predicate, SEGraph<StoragePolicySelector, SEBase>&)
{
    struct DoNotUseThisMethodException {};
    throw DoNotUseThisMethodException();
}
}
This macro is defined in definitions 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 and 25.
This macro is invoked in definition 31.


1.4.7. remove_edge_if

This method removes all edges in the graph that match Predicate. The Storage Policy will be notified before and after each edge removal.

19. non-member functions+={
template <class StoragePolicySelector, class SEBase, class Predicate>
inline void
remove_edge_if(
    Predicate predicate,
    SEGraph<StoragePolicySelector, SEBase> &g)
{
    typedef se_graph_traits<StoragePolicySelector> graph_traits;
    typedef typename graph_traits::vertex_descriptor Vertex;
    typedef typename graph_traits::edge_descriptor Edge;
    typedef typename graph_traits::base_graph_type base_type;
    typedef typename graph_traits::edge_iterator iterator;

    base_type& base_g = static_cast<base_type&>(g);

    std::vector<Edge> to_remove;
    iterator ei, ei_end;
    for(boost::tie(ei, ei_end) = boost::edges(base_g); ei != ei_end; ++ei) {
        if (predicate(*ei)) to_remove.push_back(*ei);
    }

    for(typename graph_traits::edges_size_type i = 0; i < to_remove.size(); i++) {
        Vertex u, v;
        u = boost::source(to_remove[i], base_g);
        v = boost::target(to_remove[i], base_g);
        g.will_remove_edge(u, v);
        boost::remove_edge(to_remove[i], base_g);
        g.did_remove_edge(u, v);
    }
}
}
This macro is defined in definitions 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 and 25.
This macro is invoked in definition 31.


1.4.8. clear_vertex

This method will clear all edges to and from the given vertex from the graph. The Storage Policy will be notified before and after the vertex is cleared.

20. non-member functions+={
template <class StoragePolicySelector, class SEBase>
inline void
clear_vertex(
    typename se_graph_traits<StoragePolicySelector>::vertex_descriptor u,
    SEGraph<StoragePolicySelector, SEBase> &g)
{
    typedef se_graph_traits<StoragePolicySelector> graph_traits;
    typedef typename graph_traits::base_graph_type base_type;

    base_type& base_g = static_cast<base_type&>(g);
    g.will_clear_vertex(u);
    boost::clear_vertex(u, base_g);
    g.did_clear_vertex(u);
}
}
This macro is defined in definitions 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 and 25.
This macro is invoked in definition 31.


1.4.9. clear_out_edges

This method takes a vertex and clears all the edges coming out of the vertex. The Storage Policy will be notified before and after each edge removal.

21. non-member functions+={
template <class StoragePolicySelector, class SEBase>
inline void
clear_out_edges(
    typename se_graph_traits<StoragePolicySelector>::vertex_descriptor u,
    SEGraph<StoragePolicySelector, SEBase> &g)
{
    typedef se_graph_traits<StoragePolicySelector> graph_traits;
    typedef typename graph_traits::vertex_descriptor Vertex;
    typedef typename graph_traits::edge_descriptor Edge;
    typedef typename graph_traits::base_graph_type base_type;
    typedef typename graph_traits::out_edge_iterator iterator;

    base_type& base_g = static_cast<base_type&>(g);

    iterator ei, ei_end;
    boost::tie(ei, ei_end) = boost::out_edges(u, base_g);
    std::vector<Edge> to_remove(ei, ei_end);

    for(typename graph_traits::edges_size_type i = 0; i < to_remove.size(); i++) {
        Vertex v;
        v = boost::target(to_remove[i], base_g);
        g.will_remove_edge(u, v);
        boost::remove_edge(to_remove[i], base_g);
        g.did_remove_edge(u, v);
    }
}
}
This macro is defined in definitions 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 and 25.
This macro is invoked in definition 31.


1.4.10. clear_in_edges

This method should never be called and is overloaded just to make sure.

22. non-member functions+={
template <class StoragePolicySelector, class SEBase>
inline void
clear_in_edges(
    typename se_graph_traits<StoragePolicySelector>::vertex_descriptor,
    SEGraph<StoragePolicySelector, SEBase>&)
{
    struct DoNotUseThisMethodException {};
    throw DoNotUseThisMethodException();
}
}
This macro is defined in definitions 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 and 25.
This macro is invoked in definition 31.


1.4.11. remove_vertex

remove_vertex will remove a vertex from the graph. The Storage Policy will be notified before and after the vertex removal.

23. non-member functions+={
template <class StoragePolicySelector, class SEBase>
inline void
remove_vertex(
    typename se_graph_traits<StoragePolicySelector>::vertex_descriptor u,
    SEGraph<StoragePolicySelector, SEBase> &g)
{
    typedef se_graph_traits<StoragePolicySelector> graph_traits;
    typedef typename graph_traits::base_graph_type base_type;

    base_type& base_g = static_cast<base_type&>(g);
    typename storage_traits<StoragePolicySelector>::vertex_properties_type vp = g[u];

    g.will_remove_vertex(u, vp);
    boost::remove_vertex(u, base_g);
    g.did_remove_vertex(vp);
}
}
This macro is defined in definitions 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 and 25.
This macro is invoked in definition 31.


1.4.12. merge_vertices

merge_vertices will merge the second vertex into the first. The second vertex will no longer exist, and all the edges will be copied over to the first vertex.

24. non-member functions+={
template <class StoragePolicySelector, class SEBase>
inline void
merge_vertices(
    typename se_graph_traits<StoragePolicySelector>::vertex_descriptor u,
    typename se_graph_traits<StoragePolicySelector>::vertex_descriptor v,
    SEGraph<StoragePolicySelector, SEBase> &g)
{
    typedef se_graph_traits<StoragePolicySelector> graph_traits;
    typedef typename graph_traits::base_graph_type base_type;

    base_type& base_g = static_cast<base_type&>(g);

    // step one: take all the edges from #2 and run into #1 (this is slow...)
    typename graph_traits::edge_iterator ei, ei_end;
    for(boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
        if (source(*ei, g) == v || target(*ei, g) == v) {
            // copy the edge to u
            typename graph_traits::edge_properties_type &ep = g[*ei], nep;
            nep.strength = ep.strength;

            if (source(*ei, g) == v) {
                add_edge(u, target(*ei, g), nep, g);
            } else {
                add_edge(source(*ei, g), u, nep, g);
            }
        }
    }

    // now remove the old vertex
    remove_vertex(v, g);
}
}
This macro is defined in definitions 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 and 25.
This macro is invoked in definition 31.


1.4.13. either_edge

either_edge does not exist in BOOST but is provided here for convenience. This method takes two vertices: u and v and returns a std::pair<edge_descriptor,bool>. bool will be true if an edge from either u->v or v->u is found, and false otherwise.

25. non-member functions+={
template <class StoragePolicySelector, class SEBase>
inline std::pair<typename se_graph_traits<StoragePolicySelector>::edge_descriptor, bool>
either_edge(
    typename se_graph_traits<StoragePolicySelector>::vertex_descriptor u,
    typename se_graph_traits<StoragePolicySelector>::vertex_descriptor v,
    SEGraph<StoragePolicySelector, SEBase> &g)
{
    typedef se_graph_traits<StoragePolicySelector> graph_traits;
    typedef typename graph_traits::edge_descriptor edge_desc;

    std::pair<edge_desc, bool> edge_exists = edge(u, v, g);
    if (edge_exists.second) return edge_exists;
    return edge(v, u, g);
}
}
This macro is defined in definitions 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 and 25.
This macro is invoked in definition 31.


1.4.14. ostream output

This is defined to allow an SEGraph to be output to a std::ostream.

26. global functions+={
template<class S, class B>
std::ostream & operator<<(std::ostream &o, const SEGraph<S,B> &g) {
    o << "graph: " << get_property(g, graph_name) << " (v:" << num_vertices(g) << " e:" << num_edges(g) << ")" << std::endl;
    typename se_graph_traits<S>::vertex_iterator vi, vi_end;
    for(boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) {
        typename se_graph_traits<S>::adjacency_iterator ai, ai_end;
        o << g[*vi].content << "(" << g[*vi].type_major << "): ";
        for(boost::tie(ai, ai_end) = adjacent_vertices(*vi, g); ai != ai_end; ++ai) {
            o << g[*ai].content << "(" << g[*ai].type_major << ") ";
        }
        o << std::endl;
    }
    return o;
}
}
This macro is defined in definitions 26.
This macro is invoked in definition 31.


1.5. Managing Indices

You can use the following class to manage index files. It allows manipulation of collections without creating an SEGraph object tied to a collection.

27. index manager+={
template <class StoragePolicySelector>
class index_manager : public StoragePolicy<StoragePolicySelector, empty_class>
{
    typedef StoragePolicy<StoragePolicySelector, empty_class> SEBase;
    public:
        std::vector<std::string> list_collections() {
            std::vector<std::string> collections;
            SEBase::get_collections_list(back_inserter(collections));

            return collections;
        }

        void rename_collection(std::string oldname, std::string newname) {
            SEBase::rename_collection(oldname, newname);
        }

        void remove_collection(std::string name) {
            SEBase::remove_collection(name);
        }
}; // index_manager
}
This macro is defined in definitions 27 and 28.
This macro is invoked in definition 31.

And for backwards compatibility:

28. index manager+={
template <class S>
class StorageInfoQuery : public index_manager<S> {};
}
This macro is defined in definitions 27 and 28.
This macro is invoked in definition 31.


1.6. Using Smart Pointers

If smart pointers are to be used with the SEGraph class, a convenience reference counter variable has been included in the public scope and is automatically initialized to 0 on construction.

29. SEGraph public scope+={unsigned int __refcount; }
This macro is defined in definitions 3, 4, 5, 6, 7, 8, 10, 11, 12 and 29.
This macro is invoked in definition 2.

Furthermore, if using BOOST's intrusive_ptr class, the helper functions necessary to do so are defined here:

30. BOOST intrusive_ptr functions={
namespace boost {
    template <class S, class B>
    inline void intrusive_ptr_add_ref(SEGraph<S,B> * p) {
        ++(p->__refcount);
    }
    template <class S, class B>
    inline void intrusive_ptr_release(SEGraph<S,B> * p) {
        if (--(p->__refcount) == 0)
            delete p;
    }
} // namespace boost
}
This macro is invoked in definition 31.


1.7. The File: semantic.hpp

31. File: semantic/semantic.hpp={
#ifndef _SEMANTIC_HPP_
#define _SEMANTIC_HPP_

includes

using std::string;
using std::vector;
using std::set;
using namespace boost;
using namespace semantic;

namespace semantic {

    
SEGraph

    
index manager

} // namespace semantic

namespace boost {
    
non-member functions
} // namespace boost

global functions

BOOST intrusive_ptr functions

#endif /* _SEMANTIC_HPP_ */

}
This macro is attached to an output file.


End Of File