7.40
Given a relational schema \(r(A,B,C,D)\), does \(A \twoheadrightarrow BC\) logically imply \(A \twoheadrightarrow B\) and \(A \twoheadrightarrow C\)? If yes prove it, or else give a counter example.
No. That is \(A \twoheadrightarrow BC\) does not logically imply \(A \twoheadrightarrow B\) and \(A \twoheadrightarrow C\).
It is clear that the multivalued dependency \(A \twoheadrightarrow BC\) holds on the following instance of \(r\).
A | B | C | D |
---|---|---|---|
1 | 3 | 7 | 2 |
1 | 6 | 4 | 5 |
1 | 3 | 7 | 5 |
1 | 6 | 4 | 2 |
The following Python3 code verifies exactly just that (in fact it does more than that).
from typing import List, Set, Tuple
def tuple_over_set_equality_checker(t1: Tuple, t2: Tuple, t3: Tuple, t4: Tuple, s: Set[int]) -> bool:
for i in s:
if not (t1[i] == t2[i] == t3[i] == t4[i]):
return False
return True
class Solution:
def __init__(self, doesTheMultivaluedDependencyHold=True, t1=tuple(), t2=tuple()):
'''
t1 and t2 are only meaningful if the parameter
doesTheMultivaluedDependencyHold is False. That is
if the multivalued dependency does not hold, then t1 and
t2 represent tuples in the instance of the relation that don't
have corresponding t3 and t4 to satisfy the definition of the
multivalued dependency.
'''
self.doesTheMultivaluedDependencyHold = doesTheMultivaluedDependencyHold
self.t1 = t1
self.t2 = t2
def __str__(self):
if self.doesTheMultivaluedDependencyHold:
return 'Multivalued Dependency holds!! ๐๐'
else:
return 'Multivalued Dependency does NOT hold ๐ฅ๐\n' \
'Problem causing tuples are \n\t t1: {} \n\t t2: {}'.format(self.t1, self.t2)
def multivalued_dependency_checker(r: List[Tuple], R: Set[int], alpha: Set[int], beta: Set[int]) -> bool:
'''
r: is the instance of the relation. It is basically
a list of the tuples, where each tuple represents
a row inside of the relation.
R: the schema. Is the set of integers to indicate the attributes.
It usually includes numbers from 0 upto n, where n is
some natural number.
We are testing the multivalued dependency alpha ->-> beta.
alpha and beta are subsets of R.
'''
= R - beta
R_minus_beta = len(r[0])
number_of_attributes
for i in range(0, len(r)):
for j in range(i+1, len(r)):
= r[i]
t1 = r[j]
t2
# build t3
= [0] * number_of_attributes
t3
# since t3[beta] is equal to t1[beta]
for k in beta:
= t1[k]
t3[k]
# also t3[R - beta] = t2[R - beta]
for k in R_minus_beta:
= t2[k]
t3[k]
# build t4
= [0] * number_of_attributes
t4
# since t4[beta] is equal to t2[beta]
for k in beta:
= t2[k]
t4[k]
# since t4[R - beta] is equal to t1[R - beta]
for k in R_minus_beta:
= t1[k]
t4[k]
if (not tuple_over_set_equality_checker(t1, t2, t3, t4, alpha)):
return Solution(False, t1, t2)
= tuple(t3)
t3 = tuple(t4)
t4
if (t3 in r) and (t4 in r):
# all is good
pass
else:
return Solution(False, t1, t2)
return Solution(True)
if __name__ == '__main__':
print(multivalued_dependency_checker(
[1, 3, 7, 2),
(1, 6, 4, 5),
(1, 3, 7, 5),
(1, 6, 4, 2),
(# the relation
], 0, 1, 2, 3}, # the schema
{0,}, # alpha
{1,2}, # beta
{ ))
However, the multivalued dependency \(A \twoheadrightarrow B\) does NOT hold.
The following explanation shows it does not hold.
Now letโs assume to the contrary that the multivalued dependency \(A \twoheadrightarrow B\) holds.
Take \(t_1 = (1, 3, 7, 2)\) and \(t_2 = (1, 6, 4, 5)\).
Note that the first component of \(t_1\) is value of attribute \(A\), the second component of \(t_1\) is value of attribute \(B\) and so on. Similarly for \(t_2\).
Since the multivalued dependency \(A \twoheadrightarrow B\) holds we know that there exist tuples \(t_3\) and \(t_4\) in \(r\) satisfying the conditions of the definition of multivalued dependency. Take \(\alpha := \{A\}\) and \(\beta := \{B\}\). Then \(R - \beta = \{A, C, D\}\).
We know that \(t_3[\beta] = t_1[\beta]\).
\(t_1[\beta] = t_1[\{B\}] = 3\)
Thus we know the value of the attribute \(B\) in tuple \(t_3\), it is \(3\).
We also know that \(t_3[R - \beta] = t_2[R - \beta]\).
\(t_2[R - \beta] = t_2[\{A, C, D\}] = (1, 4, 5)\)
Thus we know the value of the attributes \((A,C,D)\) of tuple \(t_3\), they are \((1, 4, 5)\).
Putting our results together, we get \(t_3 = (1, 3, 4, 5)\).
But we see that the tuple \(t_3\) doesnโt belong to the instance of \(r\) that we took.
Thus the multivalued dependency \(A \twoheadrightarrow B\) DOES NOT hold.
Therefore, \(A \twoheadrightarrow BC\) DOES NOT logically imply \(A \twoheadrightarrow B\) and \(A \twoheadrightarrow C\).