Index: boost/graph/vf2_sub_graph_iso.hpp
===================================================================
--- boost/graph/vf2_sub_graph_iso.hpp	(revision 83224)
+++ boost/graph/vf2_sub_graph_iso.hpp	(working copy)
@@ -1,5 +1,6 @@
 //=======================================================================
 // Copyright (C) 2012 Flavio De Lorenzi (fdlorenzi@gmail.com)
+// Copyright (C) 2013 Jakob Lykke Andersen, University of Southern Denmark (jlandersen@imada.sdu.dk)
 //
 // The algorithm implemented here is derived from original ideas by 
 // Pasquale Foggia and colaborators. For further information see 
@@ -372,7 +373,7 @@
     };
 
 
-    enum problem_selector { subgraph_iso, isomorphism };
+    enum problem_selector {subgraph_mono, subgraph_iso, isomorphism };
     
     // The actual state associated with both graphs
     template state1_;
       base_state state2_;
 
-      // Two helper functions used in Feasibility and Valid functions to test
+      // Three helper functions used in Feasibility and Valid functions to test
       // terminal set counts when testing for:
+	  // - graph sub-graph monomorphism, or
+      inline bool comp_term_sets(graph1_size_type a, 
+                                 graph2_size_type b,
+                                 boost::mpl::int_) const {
+        return a <= b;
+      }
+	  
       // - graph sub-graph isomorphism, or
       inline bool comp_term_sets(graph1_size_type a, 
                                  graph2_size_type b,
@@ -519,15 +527,16 @@
           BGL_FORALL_INEDGES_T(w_new, e2, graph2_, Graph2) {
             vertex2_type w = source(e2, graph2_);
             if (state2_.in_core(w) || (w == w_new)) {
-              vertex1_type v = v_new;
-              if (w != w_new)
-                v = state2_.core(w);
+              if (problem_selection != subgraph_mono) {
+                vertex1_type v = v_new;
+                if (w != w_new)
+                  v = state2_.core(w);
               
-              if (!edge1_exists(v, v_new,
-                                edge1_predicate(edge_comp_, e2), 
-                                graph1_))
-                return false;
-              
+                if (!edge1_exists(v, v_new,
+                                  edge1_predicate(edge_comp_, e2), 
+                                  graph1_))
+                  return false;
+              }
             } else {
               if (0 < state2_.in_depth(w))
                 ++term_in2_count;
@@ -545,15 +554,16 @@
           BGL_FORALL_OUTEDGES_T(w_new, e2, graph2_, Graph2) {
             vertex2_type w = target(e2, graph2_);
             if (state2_.in_core(w) || (w == w_new)) {
-              vertex1_type v = v_new;
-              if (w != w_new)
-                v = state2_.core(w);
+              if (problem_selection != subgraph_mono) {
+                vertex1_type v = v_new;
+                if (w != w_new)
+                  v = state2_.core(w);
               
-              if (!edge1_exists(v_new, v,
-                                edge1_predicate(edge_comp_, e2), 
-                                graph1_))
-                return false;
-              
+                if (!edge1_exists(v_new, v,
+                                  edge1_predicate(edge_comp_, e2), 
+                                  graph1_))
+                  return false;
+              }
             } else {
               if (0 < state2_.in_depth(w))
                 ++term_in2_count;
@@ -564,13 +574,23 @@
             }
           }
         }
-        
-        return comp_term_sets(term_in1_count, term_in2_count,
-                              boost::mpl::int_()) &&
-               comp_term_sets(term_out1_count, term_out2_count, 
-                              boost::mpl::int_()) &&
-               comp_term_sets(rest1_count, rest2_count, 
-                              boost::mpl::int_());
+		
+        if (problem_selection != subgraph_mono) { // subgraph_iso and isomorphism
+          return comp_term_sets(term_in1_count, term_in2_count,
+                                boost::mpl::int_()) &&
+                 comp_term_sets(term_out1_count, term_out2_count, 
+                                boost::mpl::int_()) &&
+                 comp_term_sets(rest1_count, rest2_count, 
+                                boost::mpl::int_());
+        } else { // subgraph_mono
+          return comp_term_sets(term_in1_count, term_in2_count,
+                                boost::mpl::int_()) &&
+                 comp_term_sets(term_out1_count, term_out2_count, 
+                                boost::mpl::int_()) &&
+                 comp_term_sets(term_in1_count + term_out1_count + rest1_count,
+                                term_in2_count + term_out2_count + rest2_count, 
+                                boost::mpl::int_());
+        }
       }
       
       // Returns true if vertex v in graph1 is a possible candidate to
@@ -790,6 +810,91 @@
 
     }
 
+    // Enumerates all graph sub-graph mono-/iso-morphism mappings between graphs
+    // graph_small and graph_large. Continues until user_callback returns true or the
+    // search space has been fully explored.
+    template 
+    bool vf2_subgraph_morphism(const GraphSmall& graph_small, const GraphLarge& graph_large,
+                          SubGraphIsoMapCallback user_callback,
+                          IndexMapSmall index_map_small, IndexMapLarge index_map_large, 
+                          const VertexOrderSmall& vertex_order_small,
+                          EdgeEquivalencePredicate edge_comp,
+                          VertexEquivalencePredicate vertex_comp) {
+
+      // Graph requirements
+      BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept ));
+      BOOST_CONCEPT_ASSERT(( VertexListGraphConcept ));
+      BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept ));
+      BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept ));
+
+      BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept ));
+      BOOST_CONCEPT_ASSERT(( VertexListGraphConcept ));
+      BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept ));
+      BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept ));
+
+      typedef typename graph_traits::vertex_descriptor vertex_small_type;
+      typedef typename graph_traits::vertex_descriptor vertex_large_type;
+
+      typedef typename graph_traits::vertices_size_type size_type_small;
+      typedef typename graph_traits::vertices_size_type size_type_large;
+        
+      // Property map requirements
+      BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept ));
+      typedef typename property_traits::value_type IndexMapSmallValue;
+      BOOST_STATIC_ASSERT(( is_convertible::value ));
+        
+      BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept ));
+      typedef typename property_traits::value_type IndexMapLargeValue;
+      BOOST_STATIC_ASSERT(( is_convertible::value ));
+
+      // Edge & vertex requirements
+      typedef typename graph_traits::edge_descriptor edge_small_type;
+      typedef typename graph_traits::edge_descriptor edge_large_type;
+
+      BOOST_CONCEPT_ASSERT(( BinaryPredicateConcept ));
+
+      BOOST_CONCEPT_ASSERT(( BinaryPredicateConcept ));
+
+      // Vertex order requirements
+      BOOST_CONCEPT_ASSERT(( ContainerConcept )); 
+      typedef typename VertexOrderSmall::value_type order_value_type;
+      BOOST_STATIC_ASSERT(( is_same::value ));
+      BOOST_ASSERT( num_vertices(graph_small) == vertex_order_small.size() );
+
+      if (num_vertices(graph_small) > num_vertices(graph_large))
+        return false;
+
+      typename graph_traits::edges_size_type num_edges_small = num_edges(graph_small);
+      typename graph_traits::edges_size_type num_edges_large = num_edges(graph_large);
+
+      // Double the number of edges for undirected graphs: each edge counts as
+      // in-edge and out-edge
+      if (is_undirected(graph_small)) num_edges_small *= 2;
+      if (is_undirected(graph_large)) num_edges_large *= 2;
+      if (num_edges_small > num_edges_large)
+        return false;
+    
+      if ((num_vertices(graph_small) == 0) && (num_vertices(graph_large) == 0))
+        return true;
+
+      detail::state 
+        s(graph_small, graph_large, index_map_small, index_map_large, edge_comp, vertex_comp);
+
+      return detail::match(graph_small, graph_large, user_callback, vertex_order_small, s);
+    }
+	
   } // namespace detail
 
 
@@ -805,7 +910,73 @@
     return vertex_order;
   }
 
+
+  // Enumerates all graph sub-graph monomorphism mappings between graphs
+  // graph_small and graph_large. Continues until user_callback returns true or the
+  // search space has been fully explored.
+  template 
+  bool vf2_subgraph_mono(const GraphSmall& graph_small, const GraphLarge& graph_large,
+                         SubGraphIsoMapCallback user_callback,
+                         IndexMapSmall index_map_small, IndexMapLarge index_map_large, 
+                         const VertexOrderSmall& vertex_order_small,
+                         EdgeEquivalencePredicate edge_comp,
+                         VertexEquivalencePredicate vertex_comp) {
+    return detail::vf2_subgraph_morphism
+                                        (graph_small, graph_large,
+                                         user_callback,
+                                         index_map_small, index_map_large,
+                                         vertex_order_small,
+                                         edge_comp,
+                                         vertex_comp);
+  }
+
+
+  // All default interface for vf2_subgraph_iso
+  template 
+  bool vf2_subgraph_mono(const GraphSmall& graph_small, const GraphLarge& graph_large, 
+                         SubGraphIsoMapCallback user_callback) {
+    return vf2_subgraph_mono(graph_small, graph_large, user_callback, 
+                             get(vertex_index, graph_small), get(vertex_index, graph_large),
+                             vertex_order_by_mult(graph_small),
+                             always_equivalent(), always_equivalent());
+  }
+
+
+  // Named parameter interface of vf2_subgraph_iso
+  template 
+  bool vf2_subgraph_mono(const GraphSmall& graph_small, const GraphLarge& graph_large,
+                         SubGraphIsoMapCallback user_callback,
+                         const VertexOrderSmall& vertex_order_small,
+                         const bgl_named_params& params) {
+    return vf2_subgraph_mono(graph_small, graph_large, user_callback,
+                             choose_const_pmap(get_param(params, vertex_index1),
+                                               graph_small, vertex_index),
+                             choose_const_pmap(get_param(params, vertex_index2),
+                                               graph_large, vertex_index),
+                             vertex_order_small,
+                             choose_param(get_param(params, edges_equivalent_t()),
+                                          always_equivalent()),
+                             choose_param(get_param(params, vertices_equivalent_t()),
+                                          always_equivalent())
+                             );
+  }
   
+  
   // Enumerates all graph sub-graph isomorphism mappings between graphs
   // graph_small and graph_large. Continues until user_callback returns true or the
   // search space has been fully explored.
@@ -823,71 +994,13 @@
                         const VertexOrderSmall& vertex_order_small,
                         EdgeEquivalencePredicate edge_comp,
                         VertexEquivalencePredicate vertex_comp) {
-
-    // Graph requirements
-    BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept ));
-    BOOST_CONCEPT_ASSERT(( VertexListGraphConcept ));
-    BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept ));
-    BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept ));
-
-    BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept ));
-    BOOST_CONCEPT_ASSERT(( VertexListGraphConcept ));
-    BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept ));
-    BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept ));
-
-    typedef typename graph_traits::vertex_descriptor vertex_small_type;
-    typedef typename graph_traits::vertex_descriptor vertex_large_type;
-
-    typedef typename graph_traits::vertices_size_type size_type_small;
-    typedef typename graph_traits::vertices_size_type size_type_large;
-        
-    // Property map requirements
-    BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept ));
-    typedef typename property_traits::value_type IndexMapSmallValue;
-    BOOST_STATIC_ASSERT(( is_convertible::value ));
-        
-    BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept ));
-    typedef typename property_traits::value_type IndexMapLargeValue;
-    BOOST_STATIC_ASSERT(( is_convertible::value ));
-
-    // Edge & vertex requirements
-    typedef typename graph_traits::edge_descriptor edge_small_type;
-    typedef typename graph_traits::edge_descriptor edge_large_type;
-
-    BOOST_CONCEPT_ASSERT(( BinaryPredicateConcept ));
-
-    BOOST_CONCEPT_ASSERT(( BinaryPredicateConcept ));
-
-    // Vertex order requirements
-    BOOST_CONCEPT_ASSERT(( ContainerConcept )); 
-    typedef typename VertexOrderSmall::value_type order_value_type;
-    BOOST_STATIC_ASSERT(( is_same::value ));
-    BOOST_ASSERT( num_vertices(graph_small) == vertex_order_small.size() );
-
-    if (num_vertices(graph_small) > num_vertices(graph_large))
-      return false;
-
-    typename graph_traits::edges_size_type num_edges_small = num_edges(graph_small);
-    typename graph_traits::edges_size_type num_edges_large = num_edges(graph_large);
-
-    // Double the number of edges for undirected graphs: each edge counts as
-    // in-edge and out-edge
-    if (is_undirected(graph_small)) num_edges_small *= 2;
-    if (is_undirected(graph_large)) num_edges_large *= 2;
-    if (num_edges_small > num_edges_large)
-      return false;
-    
-    if ((num_vertices(graph_small) == 0) && (num_vertices(graph_large) == 0))
-      return true;
-
-    detail::state 
-      s(graph_small, graph_large, index_map_small, index_map_large, edge_comp, vertex_comp);
-
-    return detail::match(graph_small, graph_large, user_callback, vertex_order_small, s);
+    return detail::vf2_subgraph_morphism
+                                        (graph_small, graph_large,
+                                         user_callback,
+                                         index_map_small, index_map_large,
+                                         vertex_order_small,
+                                         edge_comp,
+                                         vertex_comp);
   }
 
 
Index: libs/graph/doc/vf2_sub_graph_iso.html
===================================================================
--- libs/graph/doc/vf2_sub_graph_iso.html	(revision 83224)
+++ libs/graph/doc/vf2_sub_graph_iso.html	(working copy)
@@ -87,13 +87,16 @@
       graph that preserves the edge structure of the graphs. M is said to be a
       graph-subgraph isomorphism if and only if M is an isomorphism between 
       G1 and a subgraph of G2.
+      An induced subgraph of a graph G = (V, E) is a normal subgraph
+      G' = (V', E') with the extra condition that all edges of G
+      which have both endpoints in V' are in E'.
     
     
     
-      This function finds all graph-subgraph isomorphism mappings between
+      This function finds all induced subgraph isomorphisms between
       graphs graph_small and graph_large and outputs them to
       user_callback. It continues until user_callback
-      returns true or the search space has been fully explored. vf2_subgraph_iso
+      returns false or the search space has been fully explored. vf2_subgraph_iso
       returns true if a graph-subgraph isomorphism exists and false otherwise.
       EdgeEquivalencePredicate and
       VertexEquivalencePredicate predicates are used to test whether
@@ -182,8 +185,8 @@
         and CorresondenceMap2To1 types are models
         of Readable
           Property Map and map equivalent vertices across the two
-        graphs given to vf2_subgraph_iso (or vf2_graph_iso). For
-        instance, if v is
+        graphs given to vf2_subgraph_iso (or vf2_graph_iso or
+        vf2_subgraph_mono). For instance, if v is
         from graph_small, w is from graph_large,
         and the vertices can be considered equivalent,
         then get(f, v) will be w and get(g, w) 
@@ -279,13 +282,22 @@
       function
     
     vf2_graph_iso(...)
+    vf2_subgraph_mono(...)
     
-      for isomorphism testing take the same parameters as the corresponding
-      functions vf2_subgraph_iso for subgraph isomorphism testing.
-      The algorithm finds all isomorphism mappings between graphs
-      graph1 and graph2 and outputs them to
-      user_callback. It continues until user_callback
-      returns true or the search space has been fully explored. As before,
+      for isomorphism and (not necessarily induced) subgraph isomorphism testing,
+      taking the same parameters as the corresponding functions vf2_subgraph_iso 
+      for induced subgraph isomorphism testing.
+      For vf2_graph_iso the algorithm finds all isomorphism mappings between
+      graphs graph1 and graph2 and outputs them to
+      user_callback.
+      For vf2_graph_mono the algorithm finds all mappings of graph_small
+      to subgraphs of graph_large.
+      Note that, as opposed to vf2_subgraph_iso,
+      these subgraphs need not to be induced subgraphs.
+    
+     
+      Both algorithms continues until user_callback
+      returns false or the search space has been fully explored. As before,
       EdgeEquivalencePredicate and
       VertexEquivalencePredicate predicates are used to test
       whether edges and vertices are equivalent. By default
@@ -511,7 +523,9 @@
     
     
       Copyright © 2012, Flavio De Lorenzi 
-      (fdlorenzi@gmail.com)
+      (fdlorenzi@gmail.com) 
+      Copyright © 2013, Jakob Lykke Andersen, University of Southern Denmark
+      (jlandersen@imada.sdu.dk)