* mln/core/site_set/p_vertices.hh: Add missing operator()(unsigned).
	* mln/util/graph.hh: Add missing has_v(util::vertex) and
	has_e(util::edge).
	Fix is_subgraph_of().
	* mln/util/internal/graph_vertex_psite.hh,
	* mln/util/internal/graph_edge_psite.hh: Add a missing constructor.
	* mln/util/internal/graph_psite_base.hh: Add missing graph() and
	site_set() methods.
---
 milena/ChangeLog                               |   16 ++++++
 milena/mln/core/site_set/p_vertices.hh         |   17 +++++-
 milena/mln/util/graph.hh                       |   28 +++++++++-
 milena/mln/util/internal/graph_edge_psite.hh   |   10 +++-
 milena/mln/util/internal/graph_psite_base.hh   |   70 ++++++++++++++++++++----
 milena/mln/util/internal/graph_vertex_psite.hh |   10 +++-
 6 files changed, 132 insertions(+), 19 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 048b97a..26dca4b 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -14,6 +14,22 @@
 
 2008-10-27  Guillaume Lazzara  <z(a)lrde.epita.fr>
 
+	Add missing methods in graph related classes.
+
+	* mln/core/site_set/p_vertices.hh: Add missing operator()(unsigned).
+
+	* mln/util/graph.hh: Add missing has_v(util::vertex) and
+	has_e(util::edge).
+	Fix is_subgraph_of().
+
+	* mln/util/internal/graph_vertex_psite.hh,
+	* mln/util/internal/graph_edge_psite.hh: Add a missing constructor.
+
+	* mln/util/internal/graph_psite_base.hh: Add missing graph() and
+	site_set() methods.
+
+2008-10-27  Guillaume Lazzara  <z(a)lrde.epita.fr>
+
 	Fix assertion failures on Mac.
 
 	* mln/core/contract.hh: Cast expression to bool.
diff --git a/milena/mln/core/site_set/p_vertices.hh b/milena/mln/core/site_set/p_vertices.hh
index a54b62a..cbae9fd 100644
--- a/milena/mln/core/site_set/p_vertices.hh
+++ b/milena/mln/core/site_set/p_vertices.hh
@@ -69,9 +69,11 @@ namespace mln
     typedef p_vertices<G, F> self_;
     typedef internal::site_set_base_< typename F::result, self_ > super_;
 
+  public:
+
+    /// Type of the graph this site set is based on.
     typedef G graph_t;
 
-  public:
     /// \brief Construct a graph psite set from a graph of points.
     /// \{
     p_vertices();
@@ -128,6 +130,7 @@ namespace mln
     /// \{
     const mln_result(F)& operator()(const psite& p) const;
     const mln_result(F)& operator()(const util::vertex<G>& p) const;
+    const mln_result(F)& operator()(unsigned id_v) const;
     /// \}
 
     /// Accessors.
@@ -266,9 +269,17 @@ namespace mln
   const mln_result(F)&
   p_vertices<G, F>::operator()(const util::vertex<G>& v) const
   {
-    std::cout << v.id() << std::endl;
     mln_precondition(g_->has_v(v));
-    return f_(v.id());
+    return (*this)(v.id());
+  }
+
+  template <typename G, typename F>
+  inline
+  const mln_result(F)&
+  p_vertices<G, F>::operator()(unsigned id_v) const
+  {
+    mln_precondition(g_->has_v(id_v));
+    return f_(id_v);
   }
 
   template <typename G, typename F>
diff --git a/milena/mln/util/graph.hh b/milena/mln/util/graph.hh
index 1cafb19..236edd2 100644
--- a/milena/mln/util/graph.hh
+++ b/milena/mln/util/graph.hh
@@ -152,6 +152,10 @@ namespace mln
 
       /// Check whether a vertex id \p id_v exists in the graph.
       bool has_v(unsigned id_v) const;
+      /// Check whether an edge \p v exists in the graph.
+      template <typename G>
+      bool has_v(const util::vertex<G>& v) const;
+
 
       /// Return the number of adjacent edges of vertex \p id_v.
       size_t v_nmax_nbh_edges(unsigned id_v) const;
@@ -185,6 +189,10 @@ namespace mln
 
       /// Return whether \p id_e is in the graph.
       bool has_e(unsigned id_e) const;
+      /// Return whether \p e is in the graph.
+      template <typename G>
+      bool has_e(const util::edge<G>& e) const;
+
 
       /// Return the first vertex associated to the edge \p id_e.
       unsigned v1(unsigned id_e) const;
@@ -199,7 +207,7 @@ namespace mln
       unsigned e_ith_nbh_edge(unsigned id_e, unsigned i) const;
 
       /// Return whether this graph is a subgraph
-      /// Return always false here.
+      /// Return true if g and *this have the same graph_id.
       template <typename G2>
       bool is_subgraph_of(const G2& g) const;
       /// \}
@@ -277,6 +285,14 @@ namespace mln
       return id_v < data_->vertices_.size();
     }
 
+    template <typename G>
+    inline
+    bool
+    graph::has_v(const util::vertex<G>& v) const
+    {
+      return v.graph().is_subgraph_of(*this) && has_v(v.id());
+    }
+
     inline
     size_t
     graph::v_nmax_nbh_edges(unsigned id_v) const
@@ -368,6 +384,14 @@ namespace mln
       return id_e < data_->edges_.size();
     }
 
+    template <typename G>
+    inline
+    bool
+    graph::has_e(const util::edge<G>& e) const
+    {
+      return e.graph().is_subgraph_of(*this) && has_e(e.id());
+    }
+
     inline
     unsigned
     graph::v1(unsigned id_e) const
@@ -412,7 +436,7 @@ namespace mln
     bool
     graph::is_subgraph_of(const G2& g) const
     {
-      return &g == this;
+      return g.graph_id() == this->graph_id();
     }
 
   } // end of namespace mln::util
diff --git a/milena/mln/util/internal/graph_edge_psite.hh b/milena/mln/util/internal/graph_edge_psite.hh
index 3861af6..05ad74f 100644
--- a/milena/mln/util/internal/graph_edge_psite.hh
+++ b/milena/mln/util/internal/graph_edge_psite.hh
@@ -69,6 +69,7 @@ namespace mln
 	/// \{
         edge_psite();
         edge_psite(const target_t& t);
+        edge_psite(const target_t& t, unsigned);
 	/// \}
 
 	/// Accessors
@@ -104,8 +105,15 @@ namespace mln
       template <typename G, typename F>
       inline
       edge_psite<G, F>::edge_psite(const target_t& t)
+	: super_(t)
+      {
+      }
+
+      template <typename G, typename F>
+      inline
+      edge_psite<G, F>::edge_psite(const target_t& t, unsigned id)
+	: super_(id)
       {
-        this->change_target(t);
       }
 
       template <typename G, typename F>
diff --git a/milena/mln/util/internal/graph_psite_base.hh b/milena/mln/util/internal/graph_psite_base.hh
index 5a73135..38431a8 100644
--- a/milena/mln/util/internal/graph_psite_base.hh
+++ b/milena/mln/util/internal/graph_psite_base.hh
@@ -51,6 +51,7 @@ namespace mln
 	  public internal::proxy_impl<const P&, E>
       {
         typedef Pseudo_Site< graph_psite_base<V, P, S, E> > super;
+	typedef typename S::graph_t graph_t;
 
         public:
 	/// Associated types.
@@ -59,15 +60,6 @@ namespace mln
 	typedef S target;
 	/// \}
 
-
-	/// Constructors.
-	/// \{
-        graph_psite_base();
-	/// \p t A site set.
-	/// \sa p_vertices, p_edges.
-        graph_psite_base(const target& t);
-	/// \}
-
 	/// Setters.
 	/// \{
 	/// Change the targe site set.
@@ -80,6 +72,12 @@ namespace mln
 	/// Return the target (the site set).
         const target* target_() const; // Hook to the target.
 
+	/// Return the site set (the target).
+        const target& site_set() const;
+
+	/// Return the graph associated to the target of this psite.
+	const graph_t& graph() const;
+
 	/// Check whether it is valid.
 	bool is_valid() const;
 	/// Invalidate this psite.
@@ -96,12 +94,28 @@ namespace mln
 	/// \}
 
       protected:
+	/// Constructors.
+	/// \{
+        graph_psite_base();
+	/// \p t A site set.
+	/// \sa p_vertices, p_edges.
+        graph_psite_base(const target& t);
+	/// \p t A site set.
+	/// \sa p_vertices, p_edges.
+	/// \p id The id of the element associated to this psite.
+        graph_psite_base(const target& t, unsigned id);
+	/// \}
+
 	mlc_const(target)* t_;
         V v_;
      };
 
     } // end of namespace internal
 
+    template <typename V, typename P, typename S, typename E>
+    std::ostream&
+    operator<<(std::ostream& ostr, internal::graph_psite_base<V, P, S, E>& p);
+
 } // end of namespace mln
 
 
@@ -130,6 +144,15 @@ namespace mln
 
       template <typename V, typename P, typename S, typename E>
       inline
+      graph_psite_base<V, P, S, E>::graph_psite_base(const target& t, unsigned id)
+        : t_(0)
+      {
+	change_target(t);
+	update_id(id);
+      }
+
+      template <typename V, typename P, typename S, typename E>
+      inline
       void
       graph_psite_base<V, P, S, E>::change_target(const target& new_target)
       {
@@ -145,14 +168,30 @@ namespace mln
 	v_.update_id(id);
       }
 
-      template <typename V, typename P, typename S, typename E>
+      template <typename v, typename p, typename s, typename e>
       inline
-      const typename graph_psite_base<V, P, S, E>::target*
-      graph_psite_base<V, P, S, E>::target_() const
+      const typename graph_psite_base<v, p, s, e>::target*
+      graph_psite_base<v, p, s, e>::target_() const
       {
         return t_;
       }
 
+      template <typename v, typename p, typename s, typename e>
+      inline
+      const typename graph_psite_base<v, p, s, e>::target&
+      graph_psite_base<v, p, s, e>::site_set() const
+      {
+        return *t_;
+      }
+
+      template <typename v, typename p, typename s, typename e>
+      inline
+      const typename graph_psite_base<v, p, s, e>::graph_t&
+      graph_psite_base<v, p, s, e>::graph() const
+      {
+        return t_->graph();
+      }
+
       template <typename V, typename P, typename S, typename E>
       inline
       bool
@@ -188,6 +227,13 @@ namespace mln
 
     } // end of namespace internal
 
+    template <typename V, typename P, typename S, typename E>
+    std::ostream&
+    operator<<(std::ostream& ostr, internal::graph_psite_base<V, P, S, E>& p)
+    {
+      return ostr << p.subj_();
+    }
+
 } // end of namespace mln
 
 # endif // !MLN_INCLUDE_ONLY
diff --git a/milena/mln/util/internal/graph_vertex_psite.hh b/milena/mln/util/internal/graph_vertex_psite.hh
index 3db903c..5f233e2 100644
--- a/milena/mln/util/internal/graph_vertex_psite.hh
+++ b/milena/mln/util/internal/graph_vertex_psite.hh
@@ -64,6 +64,7 @@ namespace mln
 
         vertex_psite();
         vertex_psite(const target_t& t);
+        vertex_psite(const target_t& t, unsigned id);
 
         const vertex_t& v() const;
 
@@ -93,8 +94,15 @@ namespace mln
       template <typename G, typename F>
       inline
       vertex_psite<G, F>::vertex_psite(const target_t& t)
+	: super_(t)
+      {
+      }
+
+      template <typename G, typename F>
+      inline
+      vertex_psite<G, F>::vertex_psite(const target_t& t, unsigned i)
+	: super_(t, i)
       {
-        this->change_target(t);
       }
 
       template <typename G, typename F>
-- 
1.5.6.5