2
votes

I am trying to write a procedure order(List,Result) that has a List as input and returns a list Result of ordered pairs such that:

  • the first element of the ordered pair is the position of the pair in the list, and
  • the second element of the ordered pair is the element from List n the corresponding position.

Example:

if List = [a,b,c,d], the procedure order(List,Result) outputs the list: Result = [(1,a), (2,b),(3,c),(4,d)].

I am struggling with the counter for the position of the pair in the list. I have made attempts such as:

increment(Accum,Total):-
        Total is Accum + 1.
order([],[]).
order([Head|Tail],Result):-
        order(Tail, NewTail),
        NewCount is Count + 1,
        increment(NewCount,Count),
        Result = [(Count,Head)|NewTail].

Please help anyone?

3

3 Answers

5
votes

The two clauses: NewCount is Count + 1 and increment(NewCount,Count) basically have the same meaning. You didn't make clear that Count is an input variable and it has a base case of 1, so Prolog didn't know where to start unifying values for it. For example, you should use Count as an input argument as follows (it doesn't change much if compared with your version):

order([],[], _).
order([Head|Tail],[(Count,Head)|NewTail], Count):-
        NewCount is Count + 1,
        order(Tail, NewTail, NewCount).

order(List, Result ):- order(List, Result, 1).
1
votes

If you're OK with using findall/3 then this is probably the simplest solution:

order(List, Result) :-
    findall(Index-Elem, nth1(Index, List, Elem), Result).

Note that here the key-value pairs are represented using the term -/2, which is how pairs are usually represented in Prolog, e.g. this is what keysort/2 expects.

0
votes

order(List,Result) :-
        findall((N,E),(
                    append(L0,[E|_],List),
                    length([_|L0],N)),
                Result).