Prolog与列表统一
我试图进一步理解Prolog,以及它如何处理统一。在本例中,它如何处理与列表的统一 这是我的知识库Prolog与列表统一,prolog,unification,prolog-anonymous-variable,Prolog,Unification,Prolog Anonymous Variable,我试图进一步理解Prolog,以及它如何处理统一。在本例中,它如何处理与列表的统一 这是我的知识库 member(X, [X|_]). member(X, [_|T]):- member(X, T). 如果我正确理解了这个过程。如果成员(X[X | |)不为真,则它将进入递归规则,如果X在列表T中,则[|T]与T统一 那么递归谓词中的匿名变量会发生什么变化呢?它会被丢弃吗?我很难理解列表的确切统一过程,因为[\u124; T]是两个变量,而不是一个。我只是想弄清楚统一过程是如何精确地处理列表的
member(X, [X|_]).
member(X, [_|T]):- member(X, T).
如果我正确理解了这个过程。如果成员(X[X | |)
不为真,则它将进入递归规则,如果X
在列表T
中,则[|T]
与T
统一
那么递归谓词中的匿名变量会发生什么变化呢?它会被丢弃吗?我很难理解列表的确切统一过程,因为
[\u124; T]
是两个变量,而不是一个。我只是想弄清楚统一过程是如何精确地处理列表的。列表只是一个带有的复合词。
函子:
1 ?- [_|T] = .(_,T).
true.
2 ?- [_|T] =.. X.
X = ['.', _G2393, T].
复合术语结构统一的一般过程适用于:
3 ?- [A|T] = .(B,R).
A = B,
T = R.
[A | T]
实际上是(A,T)
,因此函子(
)和算术(两个术语都是二进制的,属于算术2)匹配,因此相应的成分也匹配
是的,出于报告统一结果的目的,将忽略匿名变量\uu
。否则,它只是一个新的唯一命名变量
它进入递归规则,如果X在列表T中,则[|T]与T统一
不完全是。作为从句选择的一部分,统一发生在“继续”之前。将列表L
与[|T]
统一,就是选择它的“尾部”,并让T
引用它。例如
4 ?- L = [1,2,3], L = [_|T].
L = [1, 2, 3],
T = [2, 3].
(
为1
但未报告)。假设
为Y
member(X, [Y|T]):- member(X, T).
那么这是True
不管Y
。现在您正在“返回”成员(X,T)
。换句话说,您正在丢弃Y
并“返回”成员(X,T)。
\u
意味着,不管它是什么,忽略该变量
_u与任何其他变量一样,只是您看到的每个变量都是
作为不同的变量处理,Prolog不会向您显示它是什么
与…相结合。那里没有什么特别的行为;如果你不明白的话
关于行为,只要发明一个全新的变量并将其
在那里看看它能做什么
在本例中,函数检查列表中是否存在给定元素,因此,取列表的第一个元素,检查是否相等,如果不相等,则丢弃该元素并继续。a | B表示一个列表,其中a是头元素,B是整个剩余列表 因此,简单地解释一下算法:
将匿名变量
\uu
视为以后不需要的变量。如果你用大写字母替换。
,算法也会起作用,但是它会给你一个警告,你命名了一个从未使用过的变量。我认为你的主要问题列表如何表示为变量已经得到了充分的回答,但我觉得序言还有一些其他方面需要澄清
要理解Prolog谓词和子句,最好不要将它们视为“返回”事物的“函数”,即使是隐喻。它可以引导你走上序言中命令式思维的黑暗道路
在考虑谓词时:
(1) member(X, [X|_]).
(2) member(X, [_|T]) :- member(X, T).
将member/2
视为描述元素X
何时为列表L
成员的关系,子句是确定其何时为真的规则
我假设您已经知道如何根据其他答案(例如Will Ness的详细答案)在Prolog中表示列表
第一条规定:
(1) X
是[X|||]
的成员,无论列表的尾部是什么[X|||]
在该表示法中,变量
表示列表的尾部[X |]
,X
表示该列表的第一个元素。X
是这个列表中的一员,这一点非常正确,因此member(X[X |))是一个事实。不管列表的尾部是什么,这都是正确的,因此我们只使用。
(一个匿名变量),因为此规则不需要这些信息。从技术上讲,Prolog不会“扔掉值”,但程序员会扔掉它,因为程序员没有使用它。如果我们改为说,member(X,[X | T])。
这会很好,但我们没有使用T
。Prolog可能会实例化它,但不会使用它。这就像在C中赋值x=3
,但不使用它的值。在这种情况下,Prolog将指示关于“singleton”变量的警告。注意这些,因为这通常意味着你拼错了什么或忘记了什么
下一个规则是递归的。它说:
(2) 如果X
是该列表尾部(T
)的成员,则无论列表的第一个元素是什么,X
都是列表的成员
这里我们考虑的是一个不那么简单的情况,列表中的第一个元素可能与X
不匹配,因此member(X,L)
的真值在此规则中取决于member(X,T)
的真值,其中T
是L
的尾部(除第一个元素外的所有元素)。规则不会将成员(X,T)与成员(X,T)
统一起来,因此它不会像您所说的那样将T
与成员(X,T)
统一起来
member(b, [a,b,c]).
member(X, [X|_]).
member(X, [_|T]) :- member(X, T).
member(b, [_|[b,c]]) :- member(b, [b,c]).
| ?- member(b, [a,b,c]).
true ? ;
no
| ?-
member(E, [a,b,c]).
| ?- member(E, [a,b,c]).
E = a ?
| ?- member(E, [a,b,c]).
E = a ? ;
E = b ?