Final example discussed in class 2/21/00: Query: Find the names of customers who have accounts in all branches located in Princeton DOMAIN RELATIONAL CALCULUS: The class developed the following candidate solution (cleaned up a little): { | EXISTS A ( ( IN depositor) AND FORALL(Bn, b) (( NOT (Bn,A,b) IN acct) OR EXISTS(Bc,a) (((Bn,Bc,a) IN branch) OR NOT(Bc = `Princeton`)))) } We appear to be asking that if Bn is the branch name for account A, that the branch be in Princeton. But as it is written, any Bc <> `Princeton' satisfies the inner "EXISTS(Bc,a) ..." Closer to what we wanted is: { | EXISTS A ( ( IN depositor) AND FORALL(Bn, b) (( NOT (Bn,A,b) IN acct) OR EXISTS(a) (((Bn,`Princeton',a) IN branch))))} But this only asks that one account of depositor N be at a branch in Princeton: the A we choose to satisfy "EXISTS A ... I offered the solution from my notes: { | EXISTS A ( ( IN depositor) AND FORALL(Bn, Bc, a) (( NOT (Bn,Bc,a) IN branch) OR NOT(Bc = `Princeton`) OR EXISTS(b) ((Bn,A, b) IN acct))) } Here we are asking that there be one account (w/ acct# A) for the depositor named N so that if Bn is a branch in Princeton, then A is an account in that branch. But one account (w/ acct# A) cannot be at several branches in Princeton. Note that this condition is not satisfied if N has no accounts at any branch in Princeton because in evaluating the FORALL(Bn, Bc,a), we must include all branches with Bc=`Princeton'; for these EXISTS(b)((Bn,A,b) IN acct) needs to be true but is not. Clearly, the account numbers associated with the depositor named N must vary as well as the branch names. We cannot ask for a single acct# linked to name N. This example actually came from Silberschatz et. al. Their solution is: { | FORALL(Bn,Bc,a)( (( IN branch ) AND (Bc = `Princeton')) => EXISTS(A,b)( ( IN acct) AND ( IN depositor) )) } This says that for each branch in Princeton there is an account at that branch that has N as the depositor`s name. Note that we do want the "for all" to precede the "there exists" because we will have a different account for each branch. It looks correct to me, but textbook authors can make mistakes too, so check it out. TUPLE RELATIONAL CALCULUS: Following the strategy of the Domain Relational Calculus solution: {P | FORALL B( ((B IN branch ) AND (B.city = `Princeton' )) => EXISTS(T,D)( (T IN acct) AND (D IN depositor) AND (T.bname = B.bname) AND (T.acct# = D.acct#) AND (D.name = P.name) )) }