Released examination archive, member 4208.pdf. The original eight-page paper identifies the preliminary examination held on 17 June 2014. Questions 1–4 concern functional programming and Questions 5–8 concern analysis of algorithms. Question 5(b) permits signed integers but prints a bound containing ; for nonpositive inputs the meaningful extension uses .
Let contain the database attributes of , and let contain the given functional dependencies for . To compute the attribute closure , start with and repeatedly add for every functional dependency with , stopping when a full scan adds nothing.
Enumerate every . For each, test whether is not a superkey but becomes one on adding :
If no enumerated passes both tests, return no. A direct implementation is
for each subset X of attributes(R) minus {a}:
    if closure(X, F) != attributes(R):
        if closure(X union {a}, F) == attributes(R):
            return yes
return no
If a candidate key contains , choose . Minimality makes fail the superkey test while passes it, so the algorithm finds a witness.
Conversely, suppose an enumerated passes. Starting from , repeatedly discard any database attribute other than whose removal preserves the superkey property. The process terminates at a superkey minimal with respect to these deletions. Removing cannot leave a superkey: , and a subset of , which is not a superkey, cannot determine more database attributes than . Hence is a candidate key containing . The algorithm need not carry out this minimization to return the correct yes/no answer; it establishes why the witness test suffices.
For an explicit analysis of algorithms, let be the total encoded length of the functional dependencies, counting their left and right database attribute occurrences and delimiters. With Boolean membership arrays, one complete dependency scan costs . There are at most productive scans, followed by one unproductive scan, so a naive attribute closure costs . There are subsets and at most two attribute closure computations per subset. Thus
This is an exponential-time algorithm in the number of database attributes, not a polynomial-time claim. Subsets can be generated successively rather than stored all at once. The argument applies to functional dependencies within the database relation ; dependencies belonging to unrelated database relations do not constrain its candidate keys.
This is the 13 June 2017 preliminary examination. Questions 1–4 concern functional programming; Questions 5–8 concern algorithm design and analysis of algorithms. All 35 printed subparts are answered. Source paper: released examination archive, member a10097w1-1.pdf.
The Haskell definitions use separate question namespaces. For Question 1, hide the locally defined names with import Prelude hiding ((.), zipWith, uncurry); for Question 4 use import Prelude hiding (scanl). Alternative solve definitions are alternatives, not simultaneous duplicate declarations. Assume finite total puzzle inputs; infinite streams and partial values are treated explicitly where relevant. Operation counts separate numeric bit costs from list and comparison steps.[ref]
This is the 12 June 2018 preliminary examination. Questions 1–4 concern functional programming; Questions 5–8 concern algorithm design and analysis of algorithms. Every printed option is answered here. The complete nine-page native paper is preserved in the Oxford examination release, member a10097w1.pdf; the damaged duplicate rendition is not the source used here.
The Haskell definitions below use finite total inputs unless lazy evaluation, strict functions or infinite lazy lists are being discussed. Separate questions use separate namespaces: in particular their One constructors are unrelated, and the list-conversion function abs in Question 3 is distinct from the numeric Standard Prelude function. Treat alternative definitions of the same function separately. In a module for Question 2, use import Prelude hiding (zip, zipWith); in one for Question 3, use import Prelude hiding (abs, reverse, (++)). Other questions retain the Standard Prelude operations they use.[ref] Costs count constructor, comparison and ordinary arithmetic operations; integer bit costs and evaluating arbitrary element values are separate.