Alex5207
Alex5207

Reputation: 484

How to retrieve elements of a list of lists recursively in Prolog?

Assume you have a list like: L = [1,2, [4,5, [6], [7,8,9]], [1,2]].

Q: How can one use the basic predicates to yield X = [1,2,4,5,6,7,8,9,1,2]?

It seems difficult when the depth of the lists can be arbitrary..

Upvotes: 1

Views: 53

Answers (1)

Kintalken
Kintalken

Reputation: 773

/* When You say "It seems difficult when the depth of the lists can be arbitrary" that is not true .vus.a.vis. Prolog .

Prolog programming makes heavy use if recursive function calls and can easily recurse to fully explore any tree-like data-structure . */

  :- [library(plunit)] .

  :- abolish(flatten/2) .
  :- mode(flatten(+,-)) .

  flatten(0,_) --> [Q] , flatten(1,Q) .
  flatten(1,Q) --> \+ {is_list(Q)} , flatten(2,Q) .
  flatten(1,Q) --> \+ \+ {is_list(Q)} , flatten(3,Q) .
  flatten(2,Q) , [Q] --> flatten(0,_) .
  flatten(3,Q) --> {Q=[]} , flatten(0,_) .
  flatten(3,Q) --> {Q=[R|Ts]} , flatten(1,R) , flatten(1,Ts) .

  :- begin_tests(flatten) .

  test('1',[true(Ps=[4,5,6,7,8,9,1,2])]) :-
  flatten([4,5,[6],[7,8,9],[1,2]],Ps) .

  test('2',[true(Ps=[1,2,3,4])]) :-
  flatten([1,[2,3],[],4],Ps) .

  test('3',[true(Ps=Qs)]) :-
  flatten(Qs,Ps) .

  :- end_tests(flatten) .

/* sample run .

  ?- run_tests .

  % PL-Unit: flatten ... done               % All 3 tests passed

  ?- flatten([1,[2,3],[],4],Ps).
  Ps = [1,2,3,4].

  ?- flatten([4,5,[6],[7,8,9],[1,2]],Ps) .
  Ps = [4,5,6,7,8,9,1,2].

  ?- flatten(Qs,Ps) .
  Ps = [Qs].

*/

Upvotes: 1

Related Questions