知识卡片
空区间陷阱:FORALL在空集合上恒为真的反直觉后果
内容
当量词覆盖的允许取值集合恰好为空时(比如数据库上下文中一个当前为空的关系
变量),会出现一系列纯逻辑正确、但容易让人措手不及的结果:EXISTS x(p(x))
恒为FALSE(不存在可代入的x,无论p是什么,这个命题都为假——比如”身高超过
50英尺的人里有为IBM工作的”必为假,因为压根不存在50英尺高的人);由
[[FORALL和EXISTS可以互相定义SQL缺FORALL导致双重否定困境]]中的等价关系,
NOT EXISTS x(p(x))因此恒为TRUE,FORALL x(NOT(p(x)))同样恒为TRUE,而
且因为p可以是任意谓词、NOT p也可以是任意谓词,最终推出一个更令人惊讶的
结论:只要论域为空,FORALL x(...)不管括号里写的是什么内容都恒为TRUE
(比如”所有身高超过50英尺的人都为IBM工作”是真命题,纯粹因为压根没人身高
超过50英尺)。这个规律直接体现在数据库查询中:查询”获得供应所有零件型号
的供应商”{SX}WHERE FORALL PX(EXISTS SPX(...))——一旦数据库里当前根本
没有任何零件(P为空关系),这个查询会把全部供应商都返回,因为FORALL PX
在空论域上恒真,即使实际上一个供应商也没有真正供应任何零件。书中借这个例子
指出一个更深层的教训:逻辑虽然是数据库系统的必要基础,但不是充分基础——
用”独生子被问’你是你所有兄弟’“这个类比说明,逻辑上正确的答案(”是”)未必
是用户真正想要的、有信息量的答案(”我根本没有兄弟姐妹”),系统不应止步于
给出逻辑正确但可能误导的简单响应,必要时还应该对结果给出解释。
参考来源
- 位置:《SQL与关系数据库理论——如何编写健壮的SQL代码》第10章"SQL与逻辑"
10.6.2节"空区间"(源文件:OEBPS/text00114.html)
- 结论依据:原文明确"表达式EXISTS x(p(x))为FALSE,因为'并不存在x'……
不管括号中的是什么,表达式FORALL x(...)在没有x的情况下都会为TRUE……
在没有任何零件的情况下会返回所有供应商……逻辑对于数据库系统而言是必要的
基础,但是并不充分"。
- 原始内容:表达式EXISTS x(p(x))为FALSE,因为"并不存在x"……不管括号中
的是什么,表达式FORALL x(...)在没有x的情况下都会为TRUE……在没有任何
零件的情况下会返回所有供应商……逻辑对于数据库系统而言是必要的基础,但是
并不充分。