Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I suspect what's tripping you up here is that instead of getting the data out of the database, you're having to find it from within an explicit data structure. A first crack at this might look like this:</p> <pre><code>find(_, _, []). find(Node, Graph, [Node|Path]) :- member(r(Node,Adjacent), Graph), member(AdjNode, Adjacent), find(AdjNode, Graph, Path). </code></pre> <p>See how I'm using <code>member/2</code> to find data from within the graph. This solution isn't correct though, because it loops. An improvement might be this:</p> <pre><code>find(Node, Graph, Path) :- find(Node, Graph, Path, []). find(_, _, [], _). find(Node, Graph, [Node|Path], Seen) :- member(r(Node, Adjacent), Graph), member(AdjNode, Adjacent), \+ memberchk(AdjNode, Seen), find(AdjNode, Graph, Path, [Node|Seen]). </code></pre> <p>This one is basically the same as the above version except it has a "seen" list to track where it has already been. This still doesn't produce the output you want, but I think it will be enough to get you on the right track.</p> <p><strong>Edit</strong> in response to your edit,</p> <blockquote> <p>For starters, I think I'll need some kind of base case to abort the recursion.</p> </blockquote> <p>Yes. I chose your first case because I don't think you can safely "consume" the graph during traversal. I suppose you could use <code>select/3</code> in lieu of <code>member/2</code> and pass the graph-without-this-node onward. That might be an interesting thing to try (suggestion!).</p> <blockquote> <ul> <li>How do I make the program use the members of the list in the r(...) term as the next Start?</li> </ul> </blockquote> <p>As demonstrated, use <code>member/2</code> to retrieve things from the graph. It's funny, because you used the exact word for the predicate you need. :)</p> <blockquote> <ul> <li>How do I check if a node has already been "visited"/ How can I remove a node from a specific list in r</li> </ul> </blockquote> <p>As demonstrated in my second set of code, you have another parameter for your auxiliary predicate, and use <code>memberchk/3</code> or <code>member/3</code>.</p> <blockquote> <ul> <li>How do I put the found nodes into the Path list? Simply append? Or execute the recursive call with something like [Path|Start]?</li> </ul> </blockquote> <p>I went with the recursive call. <code>append/3</code> would be more expensive.</p> <p><strong>Edit</strong>: Using <code>findall/3</code> per Will's comment, we can find all the paths at once:</p> <pre><code>all_paths(From, Graph, Paths) :- findall(Path, find(From, Graph, Path), Paths). </code></pre> <p>You can invoke this like so:</p> <pre><code>?- all_paths(a, [r(a,[b,d]),r(b,[a,c,e]),r(c,[b]),r(d,[a,e]), r(e,[b,d,f]),r(f,[e,g]),r(g,[f])], AllPaths). </code></pre> <p>I haven't tested that but it should work.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload