转换为RA:双指/等价

时间:2019-03-04 01:31:08

标签: logic relational-algebra

(不,这不是将SQL转换为RA问题的一个;-)我想在RA中表达一阶逻辑中的公式。这应该很容易:Codd在the Relational Completeness paper中的1972年方法是证明每个FOL运算符可以在RA中等效表示。

给定关系SP

  • 标题{S# CHAR, P# CHAR, QTY INT}
  • {S#, P#}
  • 特征谓词SP( s,p,q )='供应商 s 供应数量 q p >。'

快递:'供应商'S1'和供应商'S2'提供完全相同的零件组(不考虑数量)。

公式:

∀p. (∃q1. SP('S1', p, q1) ) ⇔ (∃q2. SP('S2', p, q2) )

请注意,在S1完全不提供零件的情况下,此公式是正确的,以防S2也不提供任何零件。

这是一个是/否问题(该公式没有自由变量);因此,我期望 RA表达式必须导致没有属性的关系,如果两个供应商未提供同一组零件(公式的值为False),则返回空关系;否则,没有属性的非空关系(公式的值为True)。

进一步说明一下:通常查询会返回一些列表,例如S1提供的零件列表,而忽略了数量:SP WHERE (S# = 'S1') {P#}(或希腊语π{P#}S# = 'S1'(SP))) 。对于是/否的问题,我们仅对查询是否返回某物而不是什么感兴趣,例如供应商S1是否供应零件P456 ?: SP WHERE (S# = 'S1' AND P# ='P456') {}π{}S# = 'S1'P# = 'P456'(SP))))。

您会注意到我使用的是RA的一种变体:来自Date & Darwen教程D 。这比Codd的原始RA更易于阅读和排版(我也包括希腊字符和下标形式)。我将仅限于与Codd RA相对应的 Tutorial D 运算符。

我可以进行所需查询的逆操作:“是否有S1而不是S2提供的零件,反之亦然?”

首先是常见子表达式的几个简写

WITH S1P := SP WHERE (S# = 'S1'){P#},
     S2P := SP WHERE (S# = 'S2'){P#} :

( S1P MINUS S2P )
UNION
( S2P MINUS S1P );

对于那些喜欢希腊语的人:

S1P := π{P#}S# = 'S1'(SP))
S2P := π{P#}S# = 'S2'(SP))
(S1P \ S2P) ∪ (S2P \ S1P)

如果两个供应商提供的零件完全相同,这将返回空结果。因此,剩下要做的就是将结果投影到没有属性的情况下,并将空结果翻转为非空,反之亦然。但是Codd的RA无法表达这种翻转,即AFAICT。

将Codd 1972年的方法应用于该公式,最外面的操作是一个forall量词,因此将其转换为对存在性的否定:

¬∃p. ¬( (∃q1. SP('S1', p, q1) ) ⇔ (∃q2. SP('S2', p, q2) ) )

但是现在最外面的操作是求反。 Codd的方法只允许否定出现在嵌套内部。

我被困住了。有什么想法吗?

1 个答案:

答案 0 :(得分:-1)

如果按照Codd 1972年的规范限制RA运算符和语义,则没有RA表达式可以回答这个问题。

即使我们现在添加了RA中通常包含的运算符,我们也无法回答所提出的问题。例如,wikipedia中涉及的运算符,例如重命名为ρ,扩展(用于计算列),分组/聚合,外部联接。

根据讨论,可以说,科德没有想到期望的结果(零度关系)。我之所以说“可以说”,是因为科德从未严格定义“关系”。有Codd 1970脚注1“ R 是笛卡尔积 S1 x S2 x ... x Sn 的子集。”但没有给出 n 的下限。显然,它打算包含 n 为1的简并的“乘积”,那么为什么不允许零?

例如,SQL不支持零度表。 SQL确实支持使用伪列对可能为零度的表进行伪扩展:

SELECT 'Yes' AS Dummy FROM SP WHERE...

即使允许这样做,我也声称所提出的问题无法在SQL中回答。 (考虑SP为空的情况:然后两个供应商确实提供了相同的产品集,即空集;但是FROM SP ...只能返回一个空关系。)

已建议使用各种非标准运算符或原语(请参阅有关q和其他答案的评论)。 AFAICT没有权威性的说法可以“祝福”任何特定方法。例如,the Alice Book似乎没有考虑零度的关系。

简要调查可能的运算符/原语。 (其中任何一个在表达上都等同于其他任何一个,在某种意义上,如果我们有一个,我们可以用它来定义其他人-除了最后一个。)

返回 true / false 的人:

  • 关系比较:子集,可用于定义关系==的相等性。 (这些要求操作数必须是“与联盟兼容的”。)
  • IS_EMPTY( )(显示在教程D 中)。

返回true / false的困难在于RA中没有这样的原语。 (通常将RA运算符描述为“封闭关系”。)或者,这些运算符可以返回零度关系;但是为什么不直接去那儿呢?

返回零度关系的人:

  • 补码运算,仅适用于零度关系。 (这是q中讨论的“翻转”操作。)
  • 使Dee为基元,即非空零度关系。然后Dum =df Dee MINUS Dee;通常是 r 的补码(必须为零度)= df Dee MINUS r

  • 提供原语来表达关系文字/常量值,就像大多数编程语言都支持表达数字或String文字或更复杂的数据结构一样。那么Dum/Dee只是众多关系常数中的两个。