I am trying to make a code in which the input is a list with lists and non-lists within it and the output is a list with the lists from the first input. So, for example input listsFromList([2,3,6,[a,g],2,3,[c,d]],X)
. The output would be X = [[a,g],[c,d]]
. I am trying to do it with an accumulator. So I made this code:
listsFromList([],A) :- A.
listsFromList([H|SOURCEs],A) :-
is_list(H),
append([A],H,A),
listsFromList(SOURCEs,A).
listsFromList([H|SOURCEs],A) :-
\+ is_list(H),
listsFromList(SOURCEs,A).
It does not work if I put more than one list in the first list and also it gives a wrong output when I put one list in it. Can anyone help?
You need to modify few things. Here a solution with the same number of arguments:
listsFromList([],[]).
listsFromList([H|SOURCEs],[H|A1]) :-
is_list(H),
listsFromList(SOURCEs,A1).
listsFromList([H|SOURCEs],A) :-
\+ is_list(H),
listsFromList(SOURCEs,A).
?- listsFromList([2,3,6,[a,g],2,3,[c,d]],X).
X = [[a, g], [c, d]];
false
If you want to use append/3
, you could add an accumulator list (so increase the arity form 2 to 3), but this is unnecessary, or swap the position of append/3. Furthermore, you can add a cut ( !
) to avoid the false
solution.
Solution wiht accumulator:
listsFromList([],L,L).
listsFromList([H|SOURCEs],LIn,LO) :-
is_list(H),
append([H],LIn,L),
listsFromList(SOURCEs,L,LO).
listsFromList([H|SOURCEs],L,LO) :-
\+ is_list(H),
listsFromList(SOURCEs,L,LO).
?- listsFromList([2,3,6,[a,g],2,3,[c,d]],[],X).
X = [[c, d], [a, g]]
false
If you want to use append/2
with arity 2 of the main predicate, use:
listsFromList([],[]).
listsFromList([H|SOURCEs],L) :-
is_list(H),
listsFromList(SOURCEs,L1),
append([H],L1,L).
listsFromList([H|SOURCEs],A) :-
\+ is_list(H),
listsFromList(SOURCEs,A).
?- listsFromList([2,3,6,[a,g],2,3,[c,d]],X).
X = [[a, g], [c, d]]
false
If you want to be super fancy and super short, you can solve your problem (assuming you are running SWI Prolog) with one line:
?- include(is_list,[2,3,6,[a,g],2,3,[c,d]],X).
X = [[a, g], [c, d]]
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.