prolog谓词[子列表(Xs,Ys)]

时间:2016-10-07 13:52:40

标签: list prolog append

我是prolog的新学习者。这是我们研讨会的问题,我不知道从哪里开始。 真的很感激任何帮助。

子列表(Xs,Ys)

当Xs是包含Ys的一些元素的列表时,这与它们在列表Ys中出现的顺序相同。只要Ys是正确的列表,这应该有效。例如:

sublist([a,c,e],[a,b,c,d,e])应该会成功。

sublist([a,e,c],[a,b,c,d,e])应该失败。

sublist([a,X,d],[a,b,c,d,e])应该有两个解X = b和X = c。

sublist(X,[a,b,c])应该有八个解决方案X=[]; X=[c]; X=[b]; X=[b,c]; X=[a]; X=[a,c]; X=[a,b];X=[a,b,c]

2 个答案:

答案 0 :(得分:4)

我的实施:

sublist([], []).
sublist([H| Rest1], [H| Rest2]) :-sublist(Rest1, Rest2).
sublist(H, [_ | Rest2]) :-sublist(H, Rest2).

示例:

?- sublist(X,[a,b,c]).
X = [a, b, c] ;
X = [a, b] ;
X = [a, c] ;
X = [a] ;
X = [b, c] ;
X = [b] ;
X = [c] ;
X = [].

?- sublist([a,c,e],[a,b,c,d,e]) .
true ;
false.

?- sublist([a,e,c],[a,b,c,d,e]) .
false.

?- sublist([a,X,d],[a,b,c,d,e]).
X = b ;
X = c ;
false.

答案 1 :(得分:1)

请注意,子列表需要其元素在原始列表中是连续的。

使用该定义,通过定义辅助谓词前缀和后缀来定义子列表会更容易,示例来自Shapiro's book

prefix([], _).
prefix([X|Xs], [X,Ys]) :-
    prefix(Xs, Ys).

suffix(Xs, Xs).
suffix(Xs, [_|Ys]) :-
    suffix(Xs, Ys).

- 然后只需将子列表定义为前缀的后缀:

sublist(Xs, Ys) :-
    prefix(Ps, Ys),
    suffix(Xs, Ps).

结果:

?- sublist(X, [1,2,3]).
X = [] ;
X = [1] ;
X = [] ;
X = [1, 2] ;
X = [2] ;
X = [] ;
X = [1, 2, 3] ;
X = [2, 3] ;
X = [3] ;
X = [] ;
false.

- 或作为后缀的前缀:

sublist(Xs, Ys) :-
    prefix(Xs, Ss),
    suffix(Ss, Ys).

结果:

?- sublist(X, [1,2,3]).
X = [] ;
X = [] ;
X = [] ;
X = [] ;
X = [1] ;
X = [2] ;
X = [3] ;
X = [1, 2] ;
X = [2, 3] ;
X = [1, 2, 3] ;

但也可以做一个递归定义:

sublist(Xs, Ys) :-
    prefix(Xs, Ys).
sublist(Xs, [_|Ys]) :-
    sublist(Xs, Ys).

结果:

?- sublist(X, [1,2,3]).
X = [] ;
X = [1] ;
X = [1, 2] ;
X = [1, 2, 3] ;
X = [] ;
X = [2] ;
X = [2, 3] ;
X = [] ;
X = [3] ;
X = [] ;
false.