未找到序言成员

Prolog member not found

我在 PROLOG 中定义了一段代码:

is_member(X, [X|_]).
is_member(X, [_|T]) :-
    is_member(X, T).

我对这两个输出感到困惑:

out1:

is_member('a', ['b', 'c', 'd', 'a']).
>> True.

out2:

Chars = ['b', 'c', 'd', 'a'].
is_member('a', Chars).
>> Chars = [a|_2356]

有人可以帮我吗?我虽然输出应该是 True.。我试图理解这里的逻辑,但显然我迷路了。

感谢您提前提供任何帮助或建议。

Prolog 查询的基本工作原理如下。

首先,一个完整的查询以句点 (.)结束。当你执行:

Chars = [a, b, c, d].

这是一个完整的查询,因为它以句点结尾。当您执行查询时,Prolog 会尝试通过给定变量的某种绑定使其成功。如果能够这样做,它将只显示导致成功的变量绑定。在这种特殊情况下,解决方案很简单:Chars 绑定到 [a, b, c, d].

假设您输入以上内容,然后在后面输入:

is_member(a, Chars).

自从上一个查询完成(以句点结束)后,Prolog 将此 Chars 视为一个新变量。它不再绑定到 [a, b, c, d] 因为之前的查询结束了。 Prolog 查看此查询并确定 Chars 的哪些绑定会导致它成功。结果是:

Chars = [a|_2356]

Prolog 告诉您有效的解决方案是通过将 Chars 绑定到列表 [a|_2356] 获得的,列表 [a|_2356] 是任何以 a 作为其第一个元素的列表。您没有显示的是 Prolog 提示其他解决方案。如果您按 ;,它会向您显示 is_member(a, Chars). 查询的更多解决方案:

3 ?- is_member(a, Chars).
Chars = [a|_5034] ;
Chars = [_5032, a|_5040] ;
Chars = [_5032, _5038, a|_5046] ;
...

换句话说,is_member(a, Chars)有无限多个解。它们是将 a 作为第一个元素,a 作为第二个元素等的列表。

在 Prolog 中,如果要建立一系列必须按顺序全部为真的条件,请使用 逗号,而不是 句点,把每个条件分开,然后用句号结束​​整个事情:

4 ?- Chars = [a,b,c,d], is_member(a, Chars).
Chars = [a, b, c, d] ;
false.

此查询表示您要将 Chars 绑定到 [a, b, c, d] 确定 a 是否是 Chars 的成员. Prolog 然后说它成功地解决了一个问题,Chars = [a,b,c,d]。输入 ; 寻求更多解决方案,返回 false 因为没有其他解决方案。

让我们用 x 试试伊莎贝拉的另一个例子:

5 ?- Chars = [a,b,c,d], is_member(x, Chars).
false.

在这种情况下,Prolog 无法找到解决方案,因此它失败了(显示 false)。