Review the following complexity classes: P = polynomial time NP = non-deterministic polynomial time L = logarithmic space NL = non-deterministic logarithmic space AC^0 = constant-depth circuit complexity NC = "Nick's class" = tractable parallel class ---- What are the strict inclusion (mostly conjectured) between these classes ? For each strict inclusion give an example of one problem that is in one class but not the the next class. Choose one from the following set: -- ST-connectivity: Given a directed graph G and two nodes s,t, decide whether there exists a path from s to t -- Deterministic ST-connectivity: Given a "deterministic" directed graph G (meaning: each node x has at most one outgoing edge) and two nodes s, t, decide whether there exists a path from s to t -- Parity: Given n input bits x1, ..., xn compute their xor. -- Circuit evaluation: Given a Boolean circuit with And, Or, Not gates and n values of its inputs x1, ..., xn, compute the value of the circuit (0 or 1). ---- Consider a relational query Q. Consider the following problem: "given a database D, compute Q(D)". What is its complexity, as a function of the size of D ? This is called the "data complexity". Your answer should be one of the complexity classes above: the lower you can get, the better. (To find the answer, it helps to take some concrete query, for example Q(x) = "drinkers x that frequent some bar y that servers only beers z that x doesn't like". What is the complexity of answering Q, as a function of n = |Bar| + |Beer| + |Frequents| ?) ---- Datalog (with recursion, but no negation): Example: transitive closure T(x,y) :- R(x,y) T(x,y) :- T(x,z),T(z,y) Example: same generation: S(x,x) :- R(x,y) S(y,y) :- R(x,y) S(x,y) :- S(u,v),R(u,x),R(v,y) Example: value of a Boolean circuit with And/Not gates isZero(x) :- Value0(x) isOne(x) :- Value1(x) isZero(x) :- And(y,z,x),isZero(y) isZero(x) :- And(y,z,x),isZero(z) isOne(x) :- And(y,z,x),isOne(y),isOne(z) isZero(x) :- Not(y,x),isOne(y) isOne(x) :- Not(y,x),isZero(x) Is every datalog program monotone ? Note two things: datalog does not have negation, and keep in mind the last example. ---- Fix a datalog program P. What is the complexity of the following problem ? "Given a database D, compute P(D)" ? Hint: first answer a more basic question: how does one actually compute P(D) ? ---- Datalog with negation: how can negation and recursion coexists ? For example what is the meaning of the following program ? P(x) :- R(x), not Q(x) Q(x) :- R(x), not P(x) We will discuss two interpretation of datalog with negation in class: inflationary semantics, and stratified semantics. ---- Challenging question. Suppose you are designing Pig++, by extending it with recursion, to compute typical reachability queries as T(x,y) above. You still want Pig++ to be easily parallelizable, similarly to Pig. What extension would you propose (and why) ?