我正在测试我的新版SWI prolog并不断遇到错误:singleton变量.
例:
member(X,[X|T]).
member(X,[X|T]) :- member(X,T).
Run Code Online (Sandbox Code Playgroud)
找到列表的成员,例如:
member(yolands,[yolanda,tim])
X = yes
Run Code Online (Sandbox Code Playgroud)
但相反,我得到X和T 的单例变量错误
如果我做以下事情:
member(X,[X|_]).
member(X,[_|T]) :- member(X,T).
Run Code Online (Sandbox Code Playgroud)
它有效,但看起来很难看!
任何人都可以解释为什么允许单个变量和这个ANSI标准吗?
Cap*_*liC 15
单例变量在Prolog中是无用的,并且通过编辑拼写错误很容易引入.
我很欢迎这个警告,因为它可以轻松发现这种频繁的错误原因.
作为警告,您可以运行包含单例的代码,但最终将假设的任何值都将丢失.
我不认为ISO标准(从未听说过ANSI)禁止这样的变量.
你可以用这种方式重写你的例子
member(X, [Y|T]) :- X = Y ; member(X, T).
Run Code Online (Sandbox Code Playgroud)
然后忘记了单身人士.
Dan*_*ons 10
你有一个错误:
member(X,[X|T]) :- member(X,T).
Run Code Online (Sandbox Code Playgroud)
你实际上说的是什么(与你认为你所说的相反)是,member/2如果X位于列表的头部并出现在列表的尾部,那就是成立.这个谓词只会在列表开头的同一件事的前N个副本中成立,所以这是一个非常奇怪的事情!
?- member(X, [a,a,c]).
X = a ;
X = a ;
false.
?- member(X, [b,a,a]).
X = b ;
false.
Run Code Online (Sandbox Code Playgroud)
现在,您可以通过执行以下操作来纠正错误并仍然有单例警告:
member(X, [Y|T]) :- member(X, T).
Run Code Online (Sandbox Code Playgroud)
但这不如传统的两个头的定义或@ CapelliC的版本(+1)具有明确的OR.我认为你应该等到你更好地了解Prolog之后才能在Prolog代码美学方面投入大量资金.如果你坚持一段时间,你会发现这个警告以及匿名变量的使用.
使单例变量在Prolog中无用的原因是它们被命名,但对它们一无所知,它们对其余的计算没有影响.下划线强调,在不影响含义的情况下,绝对可以进行任何事情.是什么使得
member(X, [X|T]).
Run Code Online (Sandbox Code Playgroud)
是的,X是位置1与位置2列表头部的X相同.列表必须是空的或者有头部和尾部,但尾部的内容与此处无关,重要的是X也是头.T可能是列表的其余部分,或者它可能是一个不正确的列表,或者它可能是一个面包箱或闪电或春天的空气气味.它与事实无关member(X, [X|T]).
单身警告告诉你"你在这里保留了一个名字,但是你永远不会用这个名字来称呼任何东西." 当我收到此消息时,我做的第一件事就是用_替换名称并查看我的代码是否仍然有意义.如果没有,我有一个逻辑错误.如果是这样,那可能就没必要了.
您可以在SWI-Prolog FAQ的官方页面上阅读相关信息
出现此警告的最常见情况是:
SWI 提出了一些忽略它的方法:
_T, _X),以避免警告并记录您忽略的内容。:- style_check(-singleton).,所有警告都应该消失。