3

I have this list of lists:

 L = [[[a,b],[d,e]],[[m,f],[p,o]],[[r,l],[v,d]]].

I want to write a function using Prolog that flattens it in a way that it becomes like this :

 L = [[a,b],[c,d],[m,f],[p,o],[r,l],[v,d]].

Any suggestions? Thank you.

repeat
  • 18,496
  • 4
  • 54
  • 166
Zineb SLAM
  • 39
  • 2
  • Check this answer. http://stackoverflow.com/questions/27263004/flattening-only-one-level-of-a-list-in-prolog – vmg Jun 16 '15 at 23:41
  • 2
    You want to write a *predicate* (a Prolog rule), not a *function*. Prolog doesn't have functions. :) The question leaves open some questions as well. For example, can the original list have more than 3 levels of lists? And if so, which levels do you want removed? What should it do if the original list only has 1 or 2 levels? Should it fail? Or yield the original list? Or something else? – lurker Jun 17 '15 at 00:15
  • the context is that i am using a predicate findall and as a result it gives me this list which i will be using in another predicate , the problem is that findall gives me this list which will always be 3 levels. – Zineb SLAM Jun 17 '15 at 06:05
  • in all I will have to flatten it in to a list of 6 lists – Zineb SLAM Jun 17 '15 at 06:19
  • yes I checked , other questions were about flatenning a list to get a list of elements ,while in my case I still want my flatenned list to be a list of lists I just want to seperate my lists . – Zineb SLAM Jun 17 '15 at 09:25
  • 1
    See [this](http://stackoverflow.com/a/9787502/772868) for a version using DCGs. – false Jun 17 '15 at 11:23

2 Answers2

1

Using the predicate append/2:

?- L = [[[a,b],[d,e]],[[m,f],[p,o]],[[r,l],[v,d]]], append(L, R).
L = [[[a, b], [d, e]], [[m, f], [p, o]], [[r, l], [v, d]]],
R = [[a, b], [d, e], [m, f], [p, o], [r, l], [v, d]].

You should look at the implementation by SWI-Prolog and copy it if you need to. Leave out the must_be/2 if you must do it in GNU-Prolog.

But if you need this because of findall/3, keep in mind that there might also be a findall/4 available (not for GNU-Prolog, but SWI-Prolog has it):

$ swipl
Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.2-25-gf8c39d8)
Copyright (c) 1990-2015 University of Amsterdam, VU Amsterdam
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
Please visit http://www.swi-prolog.org for details.

For help, use ?- help(Topic). or ?- apropos(Word).

?- findall(X, between(1,3,X), Xs, Rest), findall(Y, between(7,11,Y), Rest).
Xs = [1, 2, 3, 7, 8, 9, 10, 11],
Rest = [7, 8, 9, 10, 11].

Almost every situation where you need to flatten a list could be avoided using difference lists.

  • I am actually using GNU prolog which is not making things easier , but I used the append/3 , I wrote this predicate : new_append([T1,T2,T3],Result):- append(T1,T2,Res), append(Res,T3,Result). but it is gives me something like : [a,b],[c,d],[e,f],[g,h],[i,j],[k,l]... just elements and not a list of lists (I agree that my predicate is pretty subjective because I am using only 3 lists :s ) – Zineb SLAM Jun 17 '15 at 10:54
  • because I am using Gnu prolog , the append/2 doesn't work, it gives me this error: uncaught exception: error(existence_error(procedure,append/2),top_level/0) – Zineb SLAM Jun 17 '15 at 11:08
  • it worked finally , what I did is I used the append after my 2 findall every time inside my predicate , here is it in case it might help someone – Zineb SLAM Jun 17 '15 at 11:10
  • ok, I think there is an misunderstunding , yes I did look in the link from the first time , do I have to write all that predicate append with the mus_be ? like I have to define a predicate append/2 ? – Zineb SLAM Jun 17 '15 at 11:14
0
possible_moves(Tray,PossibleMoves):-
    findall([J,1,X,Y],possible_move(Tray,[J,1,X,Y]),T1),
    findall([J,2,X,Y],possible_move(Tray,[J,2,X,Y]),T2),
    append(T1,T2,Res),
    findall([J,3,X,Y],possible_move(Tray,[J,3,X,Y]),T3),
    append(Res,T3,PossibleMoves).
false
  • 10,264
  • 13
  • 101
  • 209
Zineb SLAM
  • 39
  • 2