【问题标题】:Define a predicate in prolog在 prolog 中定义谓词
【发布时间】:2018-04-26 00:01:03
【问题描述】:

定义sublist(Xs, Ys): 当Xs 是一个包含Ys 的一些元素的列表时,这成立,它们出现在列表Ys 中的顺序相同。比如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].这八个解

我的解决办法是这样的:

sublist([],[]).
sublist([],[_|_]).
sublist([X|Xs],[Y|Ys]):- (
X=Y->sublist(Xs,Ys);
sublist([X|Xs],Ys)
).

但是,它只输出:

X = [] ;
X = [a] ;
X = [a, b] ;
X = [a, b, c].

我的解决方案有什么问题?

【问题讨论】:

  • 您使用的是 if-then-else,所以它从不尝试第二个合取。如果您尝试追踪,这将是显而易见的。 (当任一变量未实例化时,调用X=Y 将始终成功)。

标签: prolog


【解决方案1】:

正如评论中所说,问题出在您的 if 语句中。你应该像这样重写你的程序:

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

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

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

顺便说一句,sublist/2 是 SWI 中的内置谓词。您可以查看该实现(取自here):

sublist(L, L).
sublist(Sub, [H|T]) :-
    sublist_(T, H, Sub).

sublist_(Sub, _, Sub).
sublist_([H|T], _, Sub) :-
    sublist_(T, H, Sub).
sublist_([H|T], X, [X|Sub]) :-
    sublist_(T, H, Sub).

【讨论】: