Prolog 查找列表的连续子列表

Prolog 查找列表的连续子列表,prolog,Prolog,我想编写一个谓词split/2,它生成在另一个列表中找到的所有连续列表 示例:split([1,2,3,4],X)应返回 X=[4],X=[2,3],X=[1,2],X=[1,2,3]等 到目前为止,我只有一个谓词返回列表中所有可能的子列表: sublist([],[]). sublist([H|T], [H|R]) :- sublist(T,R). sublist([_|T], R) :- sublist(T,R). 但是,对于示例中的查询,该谓词包含不需要的答案,如[1

我想编写一个谓词
split/2
,它生成在另一个列表中找到的所有连续列表


示例:
split([1,2,3,4],X)
应返回
X=[4]
X=[2,3]
X=[1,2]
X=[1,2,3]

到目前为止,我只有一个谓词返回列表中所有可能的子列表:

sublist([],[]).
sublist([H|T], [H|R]) :-
    sublist(T,R).
sublist([_|T], R) :-
    sublist(T,R).


但是,对于示例中的查询,该谓词包含不需要的答案,如[1,2,3,4]中未连续找到的
X=[2,4]
X=[1,3]

如果将其拆分为子问题,通常问题更容易解决。我们可以首先构造一个谓词,该谓词将构造给定列表的所有后缀

我们可以构造如下谓词:

suffix(_, []).
suffix([H|T], [H|T2]) :-
    suffix(T, T2).
因此,对于列表中的每个点,我们可以决定停止(使用空列表)或发出下一项。对于给定的样本列表,我们得到:

?- suffix([1,2,3,4],X).
X = [] ;
X = [1] ;
X = [1, 2] ;
X = [1, 2, 3] ;
X = [1, 2, 3, 4].
现在我们只需要决定什么时候开始后缀。对于列表中的每个项目,我们可以决定从该点开始,并枚举所有后缀,然后附加到该项目:

split([H|T], [H|S]) :-
    suffix(T, S).
split([_|T], S) :-
    split(T, S).
例如:

?- split([1,2,3,4],X).
X = [1] ;
X = [1, 2] ;
X = [1, 2, 3] ;
X = [1, 2, 3, 4] ;
X = [2] ;
X = [2, 3] ;
X = [2, 3, 4] ;
X = [3] ;
X = [3, 4] ;
X = [4] ;
false.
好在我们得到了第二个谓词“for free”:我们还可以获得列表的所有后缀


我们可能还希望包括空列表。我把这个留作练习。

通常,如果将问题分解为子问题,问题会更容易解决。我们可以首先构造一个谓词,该谓词将构造给定列表的所有后缀

我们可以构造如下谓词:

suffix(_, []).
suffix([H|T], [H|T2]) :-
    suffix(T, T2).
因此,对于列表中的每个点,我们可以决定停止(使用空列表)或发出下一项。对于给定的样本列表,我们得到:

?- suffix([1,2,3,4],X).
X = [] ;
X = [1] ;
X = [1, 2] ;
X = [1, 2, 3] ;
X = [1, 2, 3, 4].
现在我们只需要决定什么时候开始后缀。对于列表中的每个项目,我们可以决定从该点开始,并枚举所有后缀,然后附加到该项目:

split([H|T], [H|S]) :-
    suffix(T, S).
split([_|T], S) :-
    split(T, S).
例如:

?- split([1,2,3,4],X).
X = [1] ;
X = [1, 2] ;
X = [1, 2, 3] ;
X = [1, 2, 3, 4] ;
X = [2] ;
X = [2, 3] ;
X = [2, 3, 4] ;
X = [3] ;
X = [3, 4] ;
X = [4] ;
false.
好在我们得到了第二个谓词“for free”:我们还可以获得列表的所有后缀

我们可能还希望包括空列表。我把这当作练习