简体   繁体   中英

Take out first elements from nested lists in Prolog

Problem: I need to transform this list: [[1,2],[3,4],[5,6]] to [1,3,5] , by taking only first items from each sub-list in first list and creating new list with all of them. Language is SWI-Prolog .

My solution : To do this, I wrote this code:

getFirstItems([], Result).
getFirstItems([H|T], Result) :-
    [H2|T2] = H, 
    append(Result,H2,Result2),
    getFirstItems(T, Result2).

Issue : But this fails to infinite recursion when tail always equals to [[5,6]]

Question : how to solve this issue and solve this problem correctly?

You are complicating things too much. You need to reason with a declarative mindset, and thus implement what the relationships between the list of lists and the list of first elements are .

Here is a solution:

first_items([], []).
first_items([[H|_]|T], [H|T2]) :-
    first_items(T, T2).

Indeed, the only two things we need to state to describe that relationship are:

  • If the list of lists is empty, then so is the list of first elements.
  • a first element H is in the list of first elements, followed by the first elements ( T2 ) of the rest of the list of lists ( T ).

Example queries:

?- first_items([[1,2],[3,4],[5,6]], Z).
Z = [1, 3, 5].

?- first_items(L, [1,3,4]).
L = [[1|_22058], [3|_22070], [4|_22082]].

?- first_items(L, Z).
L = Z, Z = [] ;
L = [[_22048|_22050]],
Z = [_22048] ;
L = [[_22048|_22050], [_22066|_22068]],
Z = [_22048, _22066]
…

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