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