简体   繁体   中英

Make a list of consecutive pairs in prolog

I want to make a list of consecutive pairs from a given list, eg
given [1,2,3] it returns X=[[1,2],[2,3]]
I'm a bit confused with the recursions.
I tried with the code above, it returns me the pairs (one at a time) but the append doesn't work.

pair_list([X,Y|_], [X,Y]):- 
  append([[X,Y]],[,],L),
  write(L). 

pair_list([_|Tail], XY):- 
  pair_list(Tail,XY).

Learning recursion is essential, so go with damianodamiano' answer. Then consider the basic 'all solutions' tools, like findall/3:

?- L=[1,2,3],findall([X,Y],append(_,[X,Y|_],L),Ps).
L = [1, 2, 3],
Ps = [[1, 2], [2, 3]].

First, let's consider the following points:

  • A clean representation of pairs is important.

    • Do not use "comma lists" [A,B] or "comma pairs" (A,B) .

    • Instead, use compound terms having the form AB .

  • Stick to the logically pure subset of Prolog for maximum code versatility.

A straightforward implementation goes like this:

list_adjitems([], []).
list_adjitems([E|Es], Xs) :-
   list_adjitems_previous(Es, Xs, E).

list_adjitems_previous([], [], _).                    % auxiliary predicate
list_adjitems_previous([E1|Es], [E0-E1|Xs], E0) :-
   list_adjitems_previous(Es, Xs, E1).

Some sample queries:

?- list_adjitems([], Xs).
Xs = [].

?- list_adjitems([a], Xs).
Xs = [].

?- list_adjitems([a,b,c], Xs).
Xs = [a-b,b-c].

Does this work in the "reverse" direction, too? (Hint: it does.)

?- list_adjitems(Es, []).
   Es = []
;  Es = [A].

?- list_adjitems(Es, [x-y,y-z,z-u,u-v]).
Es = [x,y,z,u,v].

Last, let's not forget about the most general query :

?- list_adjitems(Es, Xs).
   Es = []             , Xs = []
;  Es = [A]            , Xs = []
;  Es = [A,B]          , Xs = [A-B]
;  Es = [A,B,C]        , Xs = [A-B,B-C]
;  Es = [A,B,C,D]      , Xs = [A-B,B-C,C-D]
;  Es = [A,B,C,D,E]    , Xs = [A-B,B-C,C-D,D-E]
;  Es = [A,B,C,D,E,F]  , Xs = [A-B,B-C,C-D,D-E,E-F]
;  Es = [A,B,C,D,E,F,G], Xs = [A-B,B-C,C-D,D-E,E-F,F-G]
…                                                     % ... and so on ...

Works just like it should™.

Homework: re-run above queries with the code proposed in the other answers!

Simply write:

pair([_],[]).
pair([A,B|T],[[A,B]|T1]):-
    pair([B|T],T1).

Query:

?-pair([1,2,3],L).
L = [[1, 2], [2, 3]]

You don't need to use append/3 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM