-1

Knowledge base I'm using:

connected(1,2). 
connected(3,4). 
connected(5,6). 
connected(7,8).
connected(9,10). 
connected(12,13). 
connected(13,14). 
connected(15,16).
connected(17,18). 
connected(19,20). 
connected(4,1). 
connected(6,3).
connected(4,7). 
connected(6,11). 
connected(14,9). 
connected(11,15).
connected(16,12). 
connected(14,17). 
connected(16,19).

The question I'm trying to solve:

Suppose that you add "connected(4,3)" immediately below the fact "connected(3,4)". Running the query ?- path(3,2) results in a a loop and does not terminate. Modify path/2 using an accumulator to store the points already visited, so that it never revisits the same point when calculating the path. Then run the query ?- path(3,2) again.

The trouble I'm having here is that I'm very new to Prolog, I've not actually used an accumulator before (as far as I'm aware) and as a result I'm unsure on how to proceed. If anyone could explain to me the steps I'd have to take that would be great.

Also, I'm seeing a lot of stuff with "/2" after it - any explanation as to what this means in general?

Cheers.

false
  • 10,264
  • 13
  • 101
  • 209
notywq
  • 25
  • 3
  • 1
    You should show your `path/2`: it seems it is defined, but it is not in your question. The "`/2`" stands for the _arity_ of the functor (see here: http://www.swi-prolog.org/pldoc/man?section=glossary). And, if you googled "prolog accumulator", you will get quite some information on the topic. –  Feb 09 '15 at 13:07
  • See [these answers](http://stackoverflow.com/search?q=%5Btransitive-closure%5D+%5Bprolog%5D+closure0) – false Feb 09 '15 at 17:36

2 Answers2

0

You are not showing the definition of path/2. However, what the exercise asks from you, most probably, is to keep a list of nodes (as implicitly defined by the connections defined in connected/2) that you have already visited (probably in a list, your "accumulator"). Whenever you consider whether you should follow a connection, you should check if the path so far (your accumulator) already contains the node. This way you will avoid (infinite) cycles.

This is pretty much what your homework statement says already.

This answer is not very useful without code, but you don't provide any code, either.

0

The / notation is used for the arity of each predicate. For example, path/2 indicates that path takes 2 arguments, e.g.

path(EdgeA, EdgeB) :- connected(EdgeA, EdgeB).
path(EdgeA, EdgeB) :- connected(EdgeA, Other), connected(Other, EdgeB).

An accumulator is simply an extra argument which is updated after a goal is satisfied, as an intermediate step. It is most often a list. Let's say you want to build a range/2 predicate that takes an argument X and generates a list of integers from 1 to X (without using the built-in between predicate).

Here, you would use an accumulator in order to store each number that is generated in the range [1..X] when running the query. E.g.:

range(X, Y) :- range(X, [], Y).

range(X, Acc, Z) :- X > 0, NewX is X - 1, range(NewX, [X|Acc], Z).
range(X, Acc, Acc) :- X = 0.

New numbers generated are prepended to Acc when calling the auxiliary predicate range/3. Acc is a classic accumulator in the form of list on which you "accumulate" stuff. Instead of numbers, you can accumulate edges from your graph each time you resolve a connected goal and check, at each step, if an edge you are about to follow is already in the accumulator.

VHarisop
  • 2,816
  • 1
  • 14
  • 28