序言中的嵌套列表

nested lists in prolog

我必须把这个分开:

    [[[1,2,3,4]],[[1],[1,3],[1,2,3,4]],[[1,2,3,4]],[[1,2,3,4]]]

像这样

    w1 = [1,2,3,4]
    w2 = [1],[1,3],[1,2,3,4]
    w3 = [1,2,3,4]
    w4 = [1,2,3,4]

有人可以帮我吗?

听起来您需要遍历任意深度的嵌套列表(就像一棵树),识别它包含的 平面列表(例如,一个列表,每个其中的成员本身就是一个列表),return它找到的平面列表列表。

我们将使用一个辅助谓词,它使用 差异列表(也称为开放列表或部分列表)。

一个closed list有点像[a,b],是数据结构:.( a, .( b, [] ) )[a,b|[]],其中list终止[]差异列表(或开放列表)包含两个成员ab看起来像[a,b|T] 其中 T 是未绑定变量。它与 .( a, .( b, T ) ).

相同

差异列表的用途是,如果您跟踪它的最后一个未绑定的元素,您可以继续追加它,然后在完成后通过将最后一个元素与 [] 统一来关闭它.

所以...

我们有主谓词本身,extract/2,它沿着源列表向下运行并在每个源列表上调用帮助器,同时构建平面列表的列表。当该源列表用完时,结果列表将关闭:

extract( []     , [] ) .
extract( [X|Xs] , Ys ) :- extract(X,Ys,Y1), extract(Xs,Y1).

助手 extract/3 并没有复杂多少。它只查看传递的内容。如果那是一个

  • Non-list,持平
  • 扁平化列表,它是扁平化的
  • 对于任何 non-flat 列表,我们
    • 从它的头部递归提取扁平的东西,并且
    • 如果有 non-empty 尾巴,递归地从中提取扁平的东西。
extract( X         , [X|Ys] , Ys ) :- \+ is_list(X), !.
extract( X         , [X|Ys] , Ys ) :- flat_list(X) , !.
extract( [X]       , Ys     , Y1 ) :- extract(X,Ys,Y1).
extract( [X,X1|Xs] , Ys     , Y2 ) :- extract(X,Ys,Y1), extract([X1|Xs],Y1,Y2) .

最后我们必须定义什么构成了“平面”列表。这也很简单。如果 none 的成员是一个列表,则为扁平列表:

flat_list( []     ) .
flat_list( [X|_]  ) :- is_list(X), !, fail .
flat_list( [_|Xs] ) :- is_flat(Xs) .

将所有内容放在一起,您会得到:

extract( []     , [] ) .
extract( [X|Xs] , Ys ) :- extract(X,Ys,Y1), extract(Xs,Y1).

extract( X         , [X|Ys] , Ys ) :- \+ is_list(X), !.
extract( X         , [X|Ys] , Ys ) :- flat_list(X) , !.
extract( [X]       , Ys     , Y1 ) :- extract(X,Ys,Y1), !.
extract( [X|Xs] , Ys     , Y2 ) :- extract(X,Ys,Y1), extract(Xs,Y1,Y2) .

flat_list( []     ) .
flat_list( [X|_]  ) :- is_list(X), !, fail .
flat_list( [_|Xs] ) :- flat_list(Xs) .

您可以在此处 fiddle 使用它:https://swish.swi-prolog.org/p/extract-from-list-of-lists.pl