如何制作 X 之后所有元素的数组?

How to make an array of all elements following X?

我需要写一个谓词 next(X, List1, List2),其中 returns List2,一个直接跟在 X.

之后的元素数组

例如,

next(v1,[v1,v2,v3,v1,v2,v1,v5],L) returns L=[v2,v2,v5]
next(b,[b,k,m,b,j],L) returns L=[k,j]
next(s,[s,b,c,d,e,f,s,c,s,g],L) returns L=[b,c,g]
....

我知道必须用到递归和tail。

我想我知道逻辑和谓词应该如何工作,但我无法让它工作。如果用户输入 next(a,[a,b,c,a,b,c],L).

,下面是我希望谓词如何工作
[a,b,c,a,b,c]
%if first letter is a, put the letter after it in array L, if not - remove first letter.
%first letter is a, put b in array L, remove a from initial array.

[b,c,a,b,c]
%if first letter is a, put the letter after it in array L, if not - remove first letter.
% first letter is b, it is not a, so remove it from initial array

[c,a,b,c]
%if first letter is a, put the letter after it in array L, if not - remove first letter.
% first letter is c, it is not a, so remove it from initial array

[a,b,c]
%if first letter is a, put the letter after it in array L, if not - remove first letter.
% first letter is a, put b in array L, remove a from initial array.

[b,c]
%if first letter is a, put the letter after it in array L, if not - remove first letter.
% first letter is b, it is not a, so remove it from initial array

[c]
%if first letter is a, put the letter after it in array L, if not - remove first letter.
% first letter is c, it is not a, so remove it from initial array

这是我的:

next(X, List1, List2):-
    next(X,[X,X2|List1],X2).

我知道方括号里的部分是错误的。

更新#1:

/* X is the head of the list */
next(X, [X,Y|T1], [Y|T2]) :-
    next(X, [Y|T1], T2).

/* X is not the head of the list*/
next(X, [_|T1], [T2]) :-
    next(X, T1, T2).

/* T1 contains only one element */
    next(X, _, [T2]):-
        true.

/* T1 is empty */
    next(X,[T2]):-
        true.

更新 #1 的跟踪日志:

1 ?- 跟踪。 是的。

[trace] 1 ?- next(a,[a,c,d,e,f,a,g],S).
   Call: (6) next(a, [a, c, d, e, f, a, g], _G4792) ? creep
   Call: (7) next(a, [c, d, e, f, a, g], _G4880) ? creep
   Call: (8) next(a, [d, e, f, a, g], _G4885) ? creep
   Call: (9) next(a, [e, f, a, g], _G4888) ? creep
   Call: (10) next(a, [f, a, g], _G4891) ? creep
   Call: (11) next(a, [a, g], _G4894) ? creep
   Call: (12) next(a, [g], _G4898) ? creep
   Call: (13) next(a, [], _G4903) ? creep
   Exit: (13) next(a, [], [_G4906]) ? creep
   Exit: (12) next(a, [g], [[_G4906]]) ? creep
   Exit: (11) next(a, [a, g], [g, [_G4906]]) ? creep
   Exit: (10) next(a, [f, a, g], [[g, [_G4906]]]) ? creep
   Exit: (9) next(a, [e, f, a, g], [[[g, [_G4906]]]]) ? creep
   Exit: (8) next(a, [d, e, f, a, g], [[[[g, [_G4906]]]]]) ? creep
   Exit: (7) next(a, [c, d, e, f, a, g], [[[[[g, [_G4906]]]]]]) ? creep
   Exit: (6) next(a, [a, c, d, e, f, a, g], [c, [[[[g, [_G4906]]]]]]) ? creep
S = [c, [[[[g, [_G4906]]]]]] 

我已经从这些资源中浏览了基本级别的序言练习列表: http://www.ic.unicamp.br/~meidanis/courses/problemas-prolog/ http://www.anselm.edu/homepage/mmalita/culpro/index.html

我认为您已经定义了解决问题所需的规则,但是定义这些规则的谓词从句并不完全正确。让我们看看您定义的规则:

/* X is the head of the list */
next(X, [X,Y|T1], [Y|T2]) :-
    next(X, [Y|T1], T2).

这是我在评论中给出的列表头部与元素匹配的那个,它是正确的。

/* X is not the head of the list*/
next(X, [_|T1], [T2]) :-
    next(X, T1, T2).

这个条款有问题。它说,X 不是列表的头部,但查询 next(a, [a,b,c], T) 将匹配它,因为 X = _ 是可能的。此外,这里是所有额外括号的来源,T2 已经是一个列表,因此您不想将其放入括号中,例如 [T2]。更正后的条款是:

next(X, [Y|T1], T2) :-
    dif(X, Y),      % Or X \== Y if you don't have dif/2
    next(X, T1, T2).

第三条规则和条款:

/* T1 contains only one element */
    next(X, _, [T2]):-
        true.

这有一个问题,因为 _ 匹配 任何东西 ,而不仅仅是单个元素列表。规则说,T1 只包含一个元素。但是 T1 甚至没有出现在子句中。更正后的版本为:

/* A list with one element has no elements "next" */
next(_, [_], []).

所以在上面,第一个参数是什么不再重要,第二个参数是一个元素的任何列表,不管它是什么。结果必须为空。

最后一条规则和条款:

/* T1 is empty */
    next(X,[T2]):-
        true.

一个明显的问题是您现在只有 2 个参数。您的谓词必须有 3。如果 T1 为空,我希望中间参数为 []:

/* An empty list has no "next" values */
next(_, [], []).

您还可以将最后两个子句组合为:

next(_, T, []) :- T = [] ; T = [_].