我在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.
。我试图理解这里的逻辑,但显然我迷失了。
提前感谢您提供任何帮助或建议。
答案 0 :(得分:4)
这里的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
作为其第一个元素的列表,可以获得有效的解决方案。您没有表现出的是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 )。