正如您正确观察到的那样,is_list/1
它是不健全的,或者说是不完整的,因为它错误地表示在提出最一般的查询时没有任何解决方案。
?- is_list(Ls)。
错误的。
不存在列表?来吧!
这种不幸的特征是所有遗传类型检查谓词(如 等)所共有的atom/1
,integer/1
当这些谓词被构想时,其不正确性已经很明显,但在将那些正确反对其建议语义的人标记为“纯粹主义者”(当时缺乏这个词已经获得的互补字符)。
像这样的案例:
?- is_list(Ls), Ls = []。
错误的。
?- Ls = [], is_list(Ls)。
LS = []。
清楚地表明,从逻辑的角度来看,这种非单调测试从根本上破坏了某些东西。“Prolog(,)/2
不是逻辑连接”,是的,如果您首先在代码中使用不合逻辑的谓词。否则,(,)/2
总是目标的逻辑结合。
一个干净且逻辑正确的出路是在无法确定的情况下抛出实例化错误。
library(error)
尤其是must_be/2
在继承的不合逻辑谓词的不正确性变得难以忍受之后,即使对于 Prolog 的普通用户来说,也要朝着正确的方向前进:
?- must_be(列表,X)。
参数没有充分实例化
?- must_be(列表,[_|_])。
参数没有充分实例化
?- must_be(list, [a,b,c])。
真的。
must_be/2
易于使用,是迈向更正确逻辑程序的良好第一步。其他构造也出现在地平线上,我希望其他人评论当前状态。
现在来看实际的措辞:撇开上面概述的基本问题不谈,SWI 文档中提到的争论是检查最外层函子是否足以将术语视为列表,或者列表是否实际上必须符合归纳定义一个列表,即:
- 原子
[]
是一个列表。
- 如果
Ls
是一个列表,那么'.'(_, Ls)
就是一个列表。
请注意,在最近的 SWI 版本中,[]
它甚至不是一个原子,所以它再次打破了这个概念。