List 跳过列表元素的列表

List 跳过列表元素的列表,list,prolog,List,Prolog,我有一个嵌套列表: list = [[1, 2, 3, 4], [2, 7, 2, 1], [3, 3, 7, 5], [4, 4, 1, 7]] 我试图跳过这个嵌套列表的第一个列表,以及每个列表的第一个元素。我希望它变成这样: list = [[7, 2, 1], [3, 7, 5], [4, 1, 7]] 到目前为止,我有: % skip first list in list of lists sk

我有一个嵌套列表:

list = [[1, 2, 3, 4], 
        [2, 7, 2, 1], 
        [3, 3, 7, 5], 
        [4, 4, 1, 7]]
我试图跳过这个嵌套列表的第一个列表,以及每个列表的第一个元素。我希望它变成这样:

list = [[7, 2, 1], 
        [3, 7, 5], 
        [4, 1, 7]]
到目前为止,我有:

% skip first list in list of lists
skip_first_list([_|Tail], Tail).

% attemping to skip first element in each of the lists
skip_first_list([[_ | HeadTail] | Tail], X) :-
    skip_first_list(Tail, R),
    append(R, [HeadTail], X).
这不会产生正确的结果:

?- skip_first_list([[1, 2, 3, 4], [2, 7, 2, 1], [3, 3, 7, 5], [4, 4, 1, 7]], X).
X = [[2, 7, 2, 1], [3, 3, 7, 5], [4, 4, 1, 7]] ;
X = [[3, 3, 7, 5], [4, 4, 1, 7], [2, 3, 4]] ;
X = [[4, 4, 1, 7], [7, 2, 1], [2, 3, 4]] ;
X = [[3, 7, 5], [7, 2, 1], [2, 3, 4]] ;
false.
而我想要的是这个答案:

X = [[7, 2, 1], [3, 7, 5], [4, 1, 7]]

到目前为止,我的结果似乎表明我是以相反/不正确的顺序追加的,我该如何解决这个问题?我真的不明白Prolog计算表达式的顺序。任何人都将不胜感激

规范要求您提供一个列表列表,并且:

  • 忽略第一个子列表(不是输出的一部分);及
  • 对于剩余的子列表,所有头部也被忽略
所以我们最好把它分成两个谓词:

  • remove_heads/2
    ,删除所有子列表的头;及
  • remove\u upper\u left/2
    删除第一个子列表,然后使用上述谓词弹出子列表的标题
我们可以执行
删除\u heads/2
例如递归:

remove_heads([],[]).
remove_heads([[_|H]|T],[H|T2]) :-
    remove_heads(T,T2).
最后,我们的
remove\u左上方/2
简单地忽略列表的头部,并使用尾部调用
remove\u heads

remove_upper_left([_|T],T2) :-
    remove_heads(T,T2).
或全部:

remove_heads([],[]).
remove_heads([[_|H]|T],[H|T2]) :-
    remove_heads(T,T2).

remove_upper_left([_|T],T2) :-
    remove_heads(T,T2).
然后产生:

?- remove_upper_left([[1, 2, 3, 4], [2, 7, 2, 1], [3, 3, 7, 5], [4, 4, 1, 7]],X).
X = [[7, 2, 1], [3, 7, 5], [4, 1, 7]].
并且在相反的方向工作:

?- remove_upper_left(X, [[1, 2, 3, 4], [2, 7, 2, 1], [3, 3, 7, 5], [4, 4, 1, 7]]).
X = [_G1364, [_G1370, 1, 2, 3, 4], [_G1376, 2, 7, 2, 1], [_G1382, 3, 3, 7, 5], [_G1388, 4, 4, 1|...]].
因此,在这里,它为每个列表预先添加了一个变量,并为输出预先添加了一个变量(可能是一个子列表)

此外,我们这里有两个谓词,代价是一个:如果我们想在列表中弹出所有子列表的头,我们还可以在将来使用
remove\u heads/2