<u><b>Discussion.</b></u><br><br><b>What: </b><br>The API of the Model Graph  Visitor [MGV]. The MGV is an function that treats Model (Soprano::Model) as a big graph. Subjects and objects in statements  are vertices, and properties are edges. <br>

The input parameters to the function are initial vertices. Then function visit every vertex that can be reached from the initial vertices and every connecting edge.<br><br><b>Why:</b><br>It can be used for different algorithms:<br>

<ul><li>deep copy of the resource // see algorithm.cpp</li><li>displaying of the resources  in birds-eye view</li><li>May be some other<br></li></ul><br><b>Current implementation:</b><br>In playground base/nepomuk/webextractor/libwebextractor.<br>

Files: algorithm.h algorithm.cpp modelgraphvisitor.h<br>Application: &lt;&gt;/webextractor/runtime/graphviz. Creat a dot file for selected resource.<br>Example of the result: attached.<br><br>The current API is realy weird.<br>

template &lt; typename T, typename Node, typename NodeFunc, typename Visitor , typename NextFunc  &gt;<br>       void visit_model_graph(<br>            T base,<br>            Soprano::Model * model,<br>            const QList&lt;QUrl&gt; &amp; targets, // Start points<br>

            int depth_limit = -1,<br>            NodeFunc nodeFunc = NodeFunc(),<br>            Visitor visitor = Visitor(),<br>            NextFunc nextFunc = NextFunc(),<br>            bool caching = true // Doesn&#39;t matter for discussion<br>

) <br><br clear="all"><i>Comments</i>:<br><ul><li>T and Node are some user defined classes. T as analogue to boost::graph G and Node is analogue to  <tt>boost::graph_traits&lt;G&gt;::vertex_descriptor</tt></li><li>NodeFunc is a functor that converts Node object to Soprano::Node</li>

</ul><br>In my opinion these 3 types are unnecessary. Node can be replaced with Soprano::Node. Then NodeFunc can be discarded. And I think that T can be replaced with Soprano::Model* or discarded.<br><ul><li>Visitor. This is main class. Methods of this class are called on every vertex and every edge. Look  NullVisitor for more details ( modelgraphvisitor.h). The DotVisitor are example of visitor.<br>

</li><li>NextFunc is  a functor. For given node it must return a query( currently as String, unfortunately).   If query is not empty then it must have ?p ?o result variables. The result of the query ( if any ) is the edge(?p) and corresponding child node (?o); There is an implemntation of this class that selects all properties of the Soprano::Node ( if this node is resource node. Literal nodes are ignored because they can&#39;t have childs).</li>

</ul><b>Suggestions:</b><br>There are 2 basic ideas - use templates or use virtual methods.<br><br><i>Templates:</i><br>discard T, discard Node, discard NodeFunc<br>template &lt; typename Visitor , typename NextFunc  &gt;<br>


       void visit_model_graph(<br>
             Soprano::Model * model,<br>
            const QList&lt;QUrl&gt; &amp; targets,<br>
            int depth_limit = -1,
            <br>
            Visitor visitor = Visitor(),<br>
            NextFunc nextFunc = NextFunc(),<br>
            bool caching = true)<br><br><br><i>Virtual Methods:</i><br>void visit_model_graph(<br>            Soprano::Model * model,<br>

            const QList&lt;QUrl&gt; &amp; targets,<br>

            int depth_limit = -1,
            <br>

            VisitorInterface *  visitor = new  DummyVisitor(),<br>

            NextFuncInterface * nextFunc = new DefaultNextFunc(),<br>

            bool caching = true)<br><br><b>Remarks</b>:<br>The best possible idea is to provide apropriate  <tt>boost::graph_traits. </tt>Then  we will have full power of boost::graph library. But I have no idea how to implement <a href="file:///usr/share/doc/libboost-doc/HTML/libs/graph/doc/VertexListGraph.html">VertexListGraph</a> concept. It is required for <br>

copy_graph, bread_first_search and for many others. <br>One more problem is in <tt>BFS Visitor Concept.  </tt>I don&#39;t know<tt> boost::graph well, </tt>but due to description of the<tt>  vis.initialize_vertex(s, g)</tt> the bread_first_visit is 2-passes algorithm. At first  pass viz.initialize_vertext() will be called on every vertex and at second pass all other methods.  But Nepomuk is constantly changing, so there is no guarantee that  vertices and edges discovered in first pass will be the same as in second pass. Comment from anyone who knows boost::graph is very welcome.<br>

<br>-- <br>Sincerely yours,<br>Artem<br>