你这里有一个错误:
member(X,[X|T]) :- member(X,T).
你实际上在说什么(与你认为你在说什么相反)是,member/2
如果 X 位于列表的头部并出现在列表的尾部,则它成立。这个谓词只对列表开头的同一事物的前 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).
但这既不如具有两个头的传统定义或具有显式 OR 的 @CapelliC 版本 (+1) 好。我认为你应该等到你对 Prolog 有了更好的理解,然后再对你的 Prolog 代码美学的感觉进行大量评估。如果您坚持使用一段时间,您将体会到这个警告以及匿名变量的使用。
使单例变量在 Prolog 中无用的原因是它们被命名但对它们一无所知,并且它们对其余的计算没有影响。下划线强调绝对任何东西都可以在不影响含义的情况下进入那里。是什么使得
member(X, [X|T]).
true 是位置 1 的 X 与位置 2 的列表头部的 X 相同。列表必须为空或有头和尾,但尾部的内容与此处无关,重要的是X 也是头部。T 可能是列表的其余部分,也可能是不合适的列表,也可能是面包盒、闪电或春日空气的气味。与真假无关member(X, [X|T])
。
单例警告告诉你“你在这里为某些东西保留了一个名字,但你从来没有用那个名字来调用任何东西。” 当我收到这条消息并且它不是一个明显的错字时,我做的第一件事就是用 _ 替换名称,看看我的代码是否仍然有意义。如果没有,我有一个逻辑错误。如果是这样,那可能是不必要的。