Questions are in black, solutions in blue. These solutions will be somewhat sketchy.
Proof by induction on d. If d=0 the circuit is an input gate and the expression is a variable or negated variable. If the depth of C is d+1 then C is (D and E), (D or E), or (not D) where D and E are expressions of depth at most d. By induction D and E have boolean expressions of length at most f(d), where f is some function that is O(2d). So we get a recurrence for f of f(d+1) ≤ 2f(d) + constant, which solves to f(d) = O(2d).
The circuit must be a tree, which means it has out-degree one. If it is a tree, then the obvious conversion to an SLP yields a read-once SLP since each gate is an input to at most one other gate in a tree. Conversely, converting a read-once SLP to a circuit gets you a graph of out-degree one because each result is fed to at most one other instruction.
We simulate "gate[i] = gate[j] xor gate[k]" by:
The one instruction has become five, so our length-s SLP has become
an SLP without xor's of length at most 5s. I don't know whether this can
be improved slightly or not.
nj = not gate[j];
nk = not gate[k];
x = gate[j] and nk;
y = gate[k] and nj;
gate[i] = x or y;
We make a dynamic programming table whose entries table[i,j,t] mean "it is
possible to parenthesize the substring w[i]...w[j] to multiply to t. We
first fill in all the entries of the form
table[i,i,t] as true if w[i] = t and false
otherwise. Then we fill in all the entries of the form table[i,i+1,t]
by making table[i,i+i,t] true whenever table[i,i,r] and table[i+1,i+1,s]
are true and r*s=t in the groupoid. In general we fill in table[i,i+j,t]
by looking at all the possible ways we could have table[i,i+k,r]
and table[i+k+1,i+j,s] true where r*s=t in the groupoid and setting
table[i,i+j,t] true if any of them work.
The table is of size O(n2g) where n is the length of w and
g is the number of elements of the groupoid. Each row of O(ng) elements of
this table requires time O(ng2) to fill in, so the total running
time is O(n2g2), which is polynomial in the input size
(which is O(n+g2).
The languages U(n), A(n), and Z(n) are regular: U(n) is checking that there
is exactly one head character between each pair of #'s, and A(n) and Z(n) are
checking for specific fixed strings at the beginning or end.
To check for membership in D(n), we load the first ID onto the queue and
then check each new ID on the input tape against the previous ID that we
read off the queue. (If we are satisfied with the check, we copy the input
character onto the head of the queue as we read the matching characters off of
the tail.) The check must verify that either the corresponding characters are
equal, or that the head is present at this point of the previous ID and its
action gives rise to the corresponding contents of the new ID. This latter
operation is finite-state as long as the machine can see the relevant O(1)
characters of both ID's at the same time.
So for any given Turing machine M we can make a QM QM
that accepts all strings
except halting computations of M on valid input. So L(QM)
is equal to Σ* if and only if L(M) is empty. We have reduced
EMPTY, a co-r.e.-complete language, to Σ*-QM. It remains to
prove that Σ*-QM is in co-r.e., but this is true
because a queue machine Q is in that language iff there does not exist a
string x that is in L(Q)-bar, and it is recursive to test whether x is in
L(Q) or not.
(1) There is a position x such that for all positions y, y is
less than or equal x and x holds a 1. This is the language
Σ*1, the set of all strings ending in 1.
(2) There is a position z that is strictly between any two positions
x and y that both hold 0. So there are never two 0's in a row. The
regular expression for this is 1*(011*)*
because any such string is zero or more 1's, followed by zero or more strings
each of which is a 0 followed by one or more 1's.
(3) (∃yz:y≠z) and
∀ x: [(∀y: y ≤x) or (∀y: y ≥ x)] iff S(x).
(4) ∃xyz:S(x) and not S(y) and S(z) and (x<y) and (y<z) and
∀w [((w≤x) or (w≥y)) and ((w≤y) or (w≥z))]
Last modified 4 December 2003