Proving that a language's length is divided by 2 is undecidable - complexity-theory

How can I prove using a reduction method that a language's length is divided by 2?
L={ | is a Turing machine where |L(M)|= 0 mod 2}
I have 2 ideas but I am afraid to follow the wrong one
1) I use the reduction method with Amt and I say that the turing machine takes an x=w0.....wi as input and accept if and only if wi = 0 mod 2 .
2) I use the reduction method with NOT HALT, and I say that the turing machine will refuse any input, so the length of the turing machine will be 0 which is satisfies the condition above!
Any Suggestion ?

Here's one option. Given a TM M and a string w, build this new TM N:
N = "On input x:
If x isn't the empty string, reject.
Otherwise, run M on w.
If M accepts, accept; if M rejects, reject.
(Implicitly, if M loops on w, N loops on x.)"
This TM has the property that if M accepts w, then L(N) = {ε}, so |L(N)| = 1. Otherwise, if M doesn't accept w, then L(N) = ∅, so |L(N)| = 0.
See if you can use that in a reduction.
Here are two other approaches you could take:
Apply Rice's theorem to immediately conclude that this language is undecidable because asking whether |L(M)| is even is a nontrivial property of the RE languages.
Use the Recursion Theorem: build a TM that asks whether its language has an even number of strings in it, then chooses to accept nothing if the answer is "yes" and just the empty string if the answer is "no." This TM's language has even size if and only if it doesn't - a contradiction!

Related

Is this shortcut for modulo by a constant (C) valid? IF (A mod 2^n) > C: { -C}

Looking to do modulo operator, A mod K where...
K is a uint32_t constant, is not a power of two, and I will be using it over and over again.
A is a uint32_t variable, possibly as much as ~2^13 times larger than K.
The ISA does not have single cycle modulo or division instructions. (8-bit micro)
The naive approach seems to coincide with the naive approach to division; repeat subtraction until underflow, then keep the remainder. This would obviously have fairly bad worst case performance, but would work for any A and K.
A known fast approach which works well for a K that is some power of two, is to logical AND with that power of two -1.
From Wikipedia...
A % 2^n == A & (2^n - 1)
My knee jerk reaction is to use these two things together, and I'm wondering if that is valid?
Specifically, I figure I can use the power of two mod trick to narrow the worst case for the above subtraction method. In other words, quickly mod to the nearest power of two above my constant, then subtract my constant if necessary. Here's the code that is in the actual question, fully expanded.
A = A AND (2^n - 1) # MOD A to the next higher power of two
if A > K: # See if we are still larger than our constant
A -= K # If so, subtract. We now must be lower.
##################
# A = A MOD K ???
##################
On inspection, this should always work, and should always be fast, since the next power of two greater than K should always be such that 2K will be larger. That is, K < 2^n < 2K meaning I should only ever need one extra test, and then possibly one subtraction.
...but this seems too simple. If it worked, I'd expect to have seen it before. But I can't find an example. I can't find a counter example either though. I have checked the usual places. What am I missing?
You can't combine both the approaches. First understand why does the below equation holds true.
A % p == A & (p - 1), where p = 2^n
p will have exactly 1 set bit in it's binary representation, say it's position is x.
So all the numbers which have atleast one set bit in a position greater than x, are all divisible by p, that is why performing AND with p-1 would give all set bits less than 2^x, which is same as performing mod
But that isn't the case when p is not a power of 2.
If that didn't made sense, then take for example:
A = 18 = 10010,
K = 6 = 110,
A % K = 0
According to your approach, you will perform AND operation with A and 7 (= 2^3-1), resulting in 2, which is not the value of MOD.

How do you show that a language is in the class P?

I have two languages:
A = { <M, w> | M accepts w after running for at most 2^500 steps }
B = { <M, w, 1^t> | M accepts w after running for at most t steps }
I need to figure out if these languages are in the class P. I know a language is in the class P if it runs in poly-time. I'm pretty sure the language A runs in exponential time but I'm not quite sure if a constant like 2^500 makes it poly-time instead.
Any help appreciated, thanks!
Algorithmic time is expressed as a function of the input size. If, for any input, A takes 2^500 steps, then it is actually constant time (no matter what the input, the running time is constant), which is definitely in P.
B takes t steps, where t is presumably the size of the input, so it is linear time (the time increases linearly with the input size), which is also in P.
If you have a problem that requires, for example, 2^t steps or t! (factorial) steps, then it is NOT in P. Look up Big O notation
A language is in P, if there exist an algorithm, that can decide if a given input belongs to the language and runs in polynomial time. Polynomial time, means that you can find an upper bound by an polynomial function in the length of the input.
To address your example:
Define the algorithm AL₁ as:
For the element <M,w> run M(w).
Since M(w) takes at most a constant number c = 2⁵⁰⁰ steps, the complexity of AL₁ is bounded by a constant number, which is polynomial. AL₁ ∈ O(1). So A is in P.
Define algorithm AL₂ as:
For the element <M,w,1t> run M(w,1t).
Since M(w,1t) takes at most t steps, we have to bring the input length and t together. Notice, that the input consists of w and 1t. 1t means that the number t is input as unary (e.g. 1⁵ = 11111₁ = 5₁₀). This is important for the input length. E.g. the length of 1²⁵⁶ is 256, but the length of 256 = 2⁸ is only 8 = log₂(256) in binary.
So the input length is len(w) + t and AL₂ ∈ O(t) holds. So the complexity of AL₂ is also bounded by a polynomial and so the language B is in P.
Let me add an example to show haw important it is to differ between unary and other numeral systems.
C = { <M, w, t> | M accepts w after running for at most t steps }
C is basically like B, but t is not in unary numeral system, so the length of t is logc(t). The basis c of the logarithm does not matter, because it results only in a constant factor.
The input length is now len(w) + log(t), so O(t) is not necessary polynomial in the input length. Lets say len(w) is a constant number (for simplification) , then t = clogc(t) is exponential in the input length and thus C is not in P.

Knuth the art of computer programming ex 1.1.8

I can't figure out what Knuth meant in his instructions for an exercise 8 from Chapter 1.1.
The task is to make an efficient gcd algorithm of two positive integers m and n using his notation theta[j], phi[j], b[j] and a[j] where theta and phi are strings and a and b - positive integers which represent computational steps in this case.
Let an input be the string of the form a^mb^n.
An excellent explanation of Knuth's algorithm is given by schnaader here.
My question is how this may be connected with the direction given in the exercise to use his Algorithm E given in the book with original r (remainder) substituted by |m-n| and n substituted by min(m,n).
When Knuth says "Let the input be represented by the string a^mb^n", what he means is that the input should take the form of m number of as and n number of bs. So the input f((m,n)) where m = 3 and n = 2 would be represented by the string aaabb.
Take a moment to look back at his equation 3 in that chapter, which represents a Markov algorithm. (below)
f((σ,j)) = (σ,a_j) if θ_j does not occur in σ
f((σ,j)) = (αφ_jω,b_j) if α is the shortest string for which σ = αθ_jω
f((σ,N)) = (σ,N)
So the idea is to define the sequence for each variable j, θ_j, φ_j, a_j & b_j. This way, using the above Markov's algorithm you can specify what happens to your input string, depending on the value of j.
Now, to get onto your main question;
My question is how this may be connected with the direction given in the excercise to use his Algorithm E given in the book with original r (remainder) substituted by |m-n| and n substituted by min(m,n).
Essentially what Knuth is saying here, is that you can't do division with the above Markov's algorithm. So what's the closest thing to division? Well, essentially we can subtract the smaller number from the larger number until we're left with a remainder. For example;
10 % 4 = 2 is the same as doing the following;
10 - 4 = 6 Can we remove another 4? Yes. Do it again.
6 - 4 = 2 Can we remove another 4? No. We have our remainder.
And now we have our remainder. This is essentially what he wants you to do with our input string eg aaabb.
If you read through Knuth's suggested answer in the back of the book and work through a couple of examples you will see that this is essentially what he is doing by removing the pairs ab and then adding a c until no more pairs ab exist. Taking the example I used at the top we get the string being manipulated as such aaabb, aab, caab, ca, cca, ccb, aab (then start again)
Which is the same as r = m % n, m = n, n = r (then start again). The difference is of course that in the above we have used the modulus operator and division, but in the example above that we have only used subtraction.
I hope this helps. I actually wrote a more in-depth analysis of Knuth's variation on a Markov algorithm on my blog. So if you're still feeling a little stuck have a read through the series.

Determining whether a system of congruences has a solution

Having a system of linear congruences, I'd like to determine if it has a solution. Using simple algorithms that solve such systems is impossible, as the answer may grow exponentially.
One hypothesis I have is that if a system of congruences has no solution, then there are two of them that contradict each other. I have no idea if this holds, if it did that would lead to an easy O(n^2 log n) algo, as checking if a pair of congruences has a solution requires O(log n) time. Nevertheless for this problem I'd rather see something closer to O(n).
We may assume that no moduli exceeds 10^6, especially we can quickly factor them all to begin with. We may even further assume that the sum of all moduli doesn't exceed 10^6 (but still, their product can be huge).
As you suspect, there's a fairly simple way to determine whether the set of congruences has a solution without actually needing to build that solution. You need to:
Reduce each congruence to the form x = a (mod n) if necessary; from the comments, it sounds as though you already have this.
Factorize each modulus n as a product of prime powers: n = p1^e1 * p2^e2 * ... * pk^ek.
Replace each congruence x = a (mod n) with a collection of congruences x = a (mod pi^ei), one for each of the k prime powers you found in step 2.
And now, by the Chinese Remainder Theorem it's enough to check compatibility for each prime independently: given any two congruences x = a (mod p^e) and x = b (mod p^f), they're compatible if and only if a = b (mod p^(min(e, f)). Having determined compatibility, you can throw out the congruence with smaller modulus without losing any information.
With the right data structures, you can do all this in a single pass through your congruences: for each prime p encountered, you'll need to keep track of the biggest exponent e found so far, together with the corresponding right-hand side (reduced modulo p^e for convenience). The running time will likely be dominated by the modulus factorizations, though if no modulus exceeds 10^6, then you can make that step very fast, too, by prebuilding a mapping from each integer in the range 1 .. 10^6 to its smallest prime factor.
EDIT: And since this is supposed to be a programming site, here's some (Python 3) code to illustrate the above. (For Python 2, replace the range call with xrange for better efficiency.)
def prime_power_factorisation(n):
"""Brain-dead factorisation routine, for illustration purposes only."""
# DO NOT USE FOR LARGE n!
while n > 1:
p, pe = next(d for d in range(2, n+1) if n % d == 0), 1
while n % p == 0:
n, pe = n // p, pe*p
yield p, pe
def compatible(old_ppc, new_ppc):
"""Determine whether two prime power congruences (with the same
prime) are compatible."""
m, a = old_ppc
n, b = new_ppc
return (a - b) % min(m, n) == 0
def are_congruences_solvable(moduli, right_hand_sides):
"""Determine whether the given congruences have a common solution."""
# prime_power_congruences is a dictionary mapping each prime encountered
# so far to a pair (prime power modulus, right-hand side).
prime_power_congruences = {}
for m, a in zip(moduli, right_hand_sides):
for p, pe in prime_power_factorisation(m):
# new prime-power congruence: modulus, rhs
new_ppc = pe, a % pe
if p in prime_power_congruences:
old_ppc = prime_power_congruences[p]
if not compatible(new_ppc, old_ppc):
return False
# Keep the one with bigger exponent.
prime_power_congruences[p] = max(new_ppc, old_ppc)
else:
prime_power_congruences[p] = new_ppc
# If we got this far, there are no incompatibilities, and
# the congruences have a mutual solution.
return True
One final note: in the above, we made use of the fact that the moduli were small, so that computing prime power factorisations wasn't a big deal. But if you do need to do this for much larger moduli (hundreds or thousands of digits), it's still feasible. You can skip the factorisation step, and instead find a "coprime base" for the collection of moduli: that is, a collection of pairwise relatively prime positive integers such that each modulus appearing in your congruences can be expressed as a product (possibly with repetitions) of elements of that collection. Now proceed as above, but with reference to that coprime base instead of the set of primes and prime powers. See this article by Daniel Bernstein for an efficient way to compute a coprime base for a set of positive integers. You'd likely end up making two passes through your list: one to compute the coprime base, and a second to check the consistency.

Calculate discrete logarithm

Given positive integers b, c, m where (b < m) is True it is to find a positive integer e such that
(b**e % m == c) is True
where ** is exponentiation (e.g. in Ruby, Python or ^ in some other languages) and % is modulo operation. What is the most effective algorithm (with the lowest big-O complexity) to solve it?
Example:
Given b=5; c=8; m=13 this algorithm must find e=7 because 5**7%13 = 8
From the % operator I'm assuming that you are working with integers.
You are trying to solve the Discrete Logarithm problem. A reasonable algorithm is Baby step, giant step, although there are many others, none of which are particularly fast.
The difficulty of finding a fast solution to the discrete logarithm problem is a fundamental part of some popular cryptographic algorithms, so if you find a better solution than any of those on Wikipedia please let me know!
This isn't a simple problem at all. It is called calculating the discrete logarithm and it is the inverse operation to a modular exponentation.
There is no efficient algorithm known. That is, if N denotes the number of bits in m, all known algorithms run in O(2^(N^C)) where C>0.
Python 3 Solution:
Thankfully, SymPy has implemented this for you!
SymPy is a Python library for symbolic mathematics. It aims to become a full-featured computer algebra system (CAS) while keeping the code as simple as possible in order to be comprehensible and easily extensible. SymPy is written entirely in Python.
This is the documentation on the discrete_log function. Use this to import it:
from sympy.ntheory import discrete_log
Their example computes \log_7(15) (mod 41):
>>> discrete_log(41, 15, 7)
3
Because of the (state-of-the-art, mind you) algorithms it employs to solve it, you'll get O(\sqrt{n}) on most inputs you try. It's considerably faster when your prime modulus has the property where p - 1 factors into a lot of small primes.
Consider a prime on the order of 100 bits: (~ 2^{100}). With \sqrt{n} complexity, that's still 2^{50} iterations. That being said, don't reinvent the wheel. This does a pretty good job. I might also add that it was almost 4x times more memory efficient than Mathematica's MultiplicativeOrder function when I ran with large-ish inputs (44 MiB vs. 173 MiB).
Since a duplicate of this question was asked under the Python tag, here is a Python implementation of baby step, giant step, which, as #MarkBeyers points out, is a reasonable approach (as long as the modulus isn't too large):
def baby_steps_giant_steps(a,b,p,N = None):
if not N: N = 1 + int(math.sqrt(p))
#initialize baby_steps table
baby_steps = {}
baby_step = 1
for r in range(N+1):
baby_steps[baby_step] = r
baby_step = baby_step * a % p
#now take the giant steps
giant_stride = pow(a,(p-2)*N,p)
giant_step = b
for q in range(N+1):
if giant_step in baby_steps:
return q*N + baby_steps[giant_step]
else:
giant_step = giant_step * giant_stride % p
return "No Match"
In the above implementation, an explicit N can be passed to fish for a small exponent even if p is cryptographically large. It will find the exponent as long as the exponent is smaller than N**2. When N is omitted, the exponent will always be found, but not necessarily in your lifetime or with your machine's memory if p is too large.
For example, if
p = 70606432933607
a = 100001
b = 54696545758787
then 'pow(a,b,p)' evaluates to 67385023448517
and
>>> baby_steps_giant_steps(a,67385023448517,p)
54696545758787
This took about 5 seconds on my machine. For the exponent and the modulus of those sizes, I estimate (based on timing experiments) that brute force would have taken several months.
Discrete logarithm is a hard problem
Computing discrete logarithms is believed to be difficult. No
efficient general method for computing discrete logarithms on
conventional computers is known.
I will add here a simple bruteforce algorithm which tries every possible value from 1 to m and outputs a solution if it was found. Note that there may be more than one solution to the problem or zero solutions at all. This algorithm will return you the smallest possible value or -1 if it does not exist.
def bruteLog(b, c, m):
s = 1
for i in xrange(m):
s = (s * b) % m
if s == c:
return i + 1
return -1
print bruteLog(5, 8, 13)
and here you can see that 3 is in fact the solution:
print 5**3 % 13
There is a better algorithm, but because it is often asked to be implemented in programming competitions, I will just give you a link to explanation.
as said the general problem is hard. however a prcatical way to find e if and only if you know e is going to be small (like in your example) would be just to try each e from 1.
btw e==3 is the first solution to your example, and you can obviously find that in 3 steps, compare to solving the non discrete version, and naively looking for integer solutions i.e.
e = log(c + n*m)/log(b) where n is a non-negative integer
which finds e==3 in 9 steps

Resources