序言中的嵌套列表
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终止[]
。 差异列表(或开放列表)包含两个成员a
和b
看起来像[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
我必须把这个分开:
[[[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终止[]
。 差异列表(或开放列表)包含两个成员a
和b
看起来像[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