问题
I writing a predicate in prolog in which I give two parameters listsFromL(X,B)
. X
would be a list with lists within that list and B
would be a new list with the lists from X
.
So, for example, if I would call listsFromL([1,2,[d,a]],X).
the return would be B = [[d,a]].
and if I would add more lists to X
I would get a longer list with lists as X
.
How do I go about this?
回答1:
listsFromList([],[]) .
listsFromList([HEAD|SOURCEs],[HEAD|TARGETs])
:-
is_list(HEAD) ,
listsFromList(SOURCEs,TARGETs)
.
listsFromList([HEAD|SOURCEs],TARGETs)
:-
\+ is_list(HEAD) ,
listsFromList(SOURCEs,TARGETs)
.
/*
?- listsFromList([1,2,3,4,[a,b]],X).
X = [[a, b]] ;
false.
?- listsFromList([1,[a,b],2,[c,d],3],X).
X = [[a, b], [c, d]] ;
false.
?- listsFromList([],X).
X = [].
?-
*/
回答2:
You need:
- A predicate to filter you original list: one which detects lists: is_list/1
- A "higher-order" predicate that, given the above, filters a list which may contains lists into a list with only the lists: include/3
Now you just need to put those two Lego blocks together.
listsFromList(Stuff,OnlyLists) :-
include(is_list,Stuff,OnlyLists).
And so:
?- listsFromList([],OLs).
OLs = [].
?- listsFromList([a,b,c],OLs).
OLs = [].
?- listsFromList([a,b,[x,y],c],OLs).
OLs = [[x, y]].
回答3:
listsFromList(SOURCEs,TARGETs)
:-
phrase(listsFromList_,SOURCEs,TARGETs)
.
listsFromList_,[] --> \+ [_] .
listsFromList_,[ITEM] --> [ITEM] , { is_list(ITEM) } , listsFromList_ .
listsFromList_,[] --> [ITEM] , { \+ is_list(ITEM) } , listsFromList_ .
/*
?- listsFromList([1,2,3,4,[a,b]],X).
X = [[a, b]] ;
false.
?- listsFromList([1,2,[b,c],3,4,[a,b]],X).
X = [[b, c], [a, b]] ;
false.
?- listsFromList([],X).
X = [] ;
false.
?-
*/
来源:https://stackoverflow.com/questions/64894058/listsfromlist-function-in-prolog