Prolog谓词问题

Eps*_*tor -1 prolog

我刚刚开始使用Prolog,我无法弄清楚为什么以下内容无法正常工作.我正在尝试创建一个谓词,如果列表L2包含在L1中,则该谓词返回true.这就是我写的:

assert(contains (L1, L1)).
assert(contains(L1, [X|L2]):-member(X, L1), contains(L1, L2)).
assert(contains(L1, [])).
Run Code Online (Sandbox Code Playgroud)

我认为这将相当于"如果'L3 = X | L2'的X在L1中,并且L2在L1中则为真",包含(L1,L2)递归翻译,直到所有成员都被遍历为止我们留下最后一个选项,或者我们找到一个不在L1中的成员,它将使谓词失败.

不幸的是,它似乎没有这样的方式.它似乎只返回成员(X,L1)的值,因此包含([1,2,3],[1,4,5])通过,但包含([1,2,3],[4, 1,5])没有.

我究竟做错了什么?

Kaa*_*rel 5

我没有完全理解你的问题,但我会写这样的contains/2谓词:

% An empty list is contained by any list
contains(_, []).

% If a list is not empty, then its
% first element must be an element of L1,
% and its tail must be contained by L1.
contains(L1, [X | L2]) :-
    member(X, L1),
    contains(L1, L2).
Run Code Online (Sandbox Code Playgroud)

顺便说一下,请注意你的第一条规则(事实)

contains (L1, L1).
Run Code Online (Sandbox Code Playgroud)

是语法错误(谓词名称后面不应该有空格).此外,如果更正,它将创建一个不需要的选择点.所以,而是删除它.

如果您想assert/1在Prolog提示符上使用,请执行

?- assert(contains(_, [])).

Yes
?- assert(contains(L1, [X | L2]) :- (member(X, L1), contains(L1, L2))).

Yes
Run Code Online (Sandbox Code Playgroud)

要查看最终在知识库中的内容,请使用listing/0.

?- listing.

:- dynamic contains/2.

contains(_, []).
contains(B, [A|C]) :-
    member(A, B),
    contains(B, C).

Yes
Run Code Online (Sandbox Code Playgroud)

我不认为问题在于"断言自由变量",正如您在自己的答案中指出的那样.而是,检查您的包围.