首页 > 解决方案 > 来自列表谓词的 Prolog 列表

问题描述

我正在尝试编写一个代码,其中输入是一个列表,其中包含列表和非列表,输出是一个包含来自第一个输入的列表的列表。因此,例如输入listsFromList([2,3,6,[a,g],2,3,[c,d]],X)。输出将是X = [[a,g],[c,d]]. 我正在尝试用蓄电池来做到这一点。所以我做了这个代码:

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).

如果我在第一个列表中放置了多个列表,并且当我将一个列表放入其中时它会给出错误的输出,则它不起作用。任何人都可以帮忙吗?

标签: listprolog

解决方案


你需要修改一些东西。这是具有相同数量参数的解决方案:

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

如果您想使用append/3,您可以添加一个累加器列表(因此将 arity 形式从 2 增加到 3),但这是不必要的,或者交换 append/3 的位置。此外,您可以添加一个 cut ( !) 来避免该false解决方案。

蓄能器解决方案:

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

如果要append/2与主要谓词的 arity 2 一起使用,请使用:

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

如果你想要超级花哨和超级短,你可以用一行来解决你的问题(假设你正在运行 SWI Prolog):

?- include(is_list,[2,3,6,[a,g],2,3,[c,d]],X). 
X = [[a, g], [c, d]]

推荐阅读