0

I am studying algorithms and I came across this exercise:

'Prove that there is no program/algorithm that determines if a program P uses an uninitialized variable on a given input x.'

Here is the proof I came up with:

Let's assume that there is an algorithm Det to determine if a program P uses an uninitialized variable on a given input x.

Let the program be

P(x) if Det(P,x) is true do nothing else variable i print i

Here we see a contradiction. If Det(P,x) is false then we have used an uninitialized variable. We have not used uninitialized variable elsewhere so whenever it returns true, its wrong.

I am not sure if I am thinking in the right way.

a_123
  • 183
  • 2
  • 13

1 Answers1

2

I think you almost have it, but you have to say a bit more to truly show the contradiction.

Your program is perfect, i.e. 'P(x): if Det(P,x) is true do nothing else variable i print i'. You've also shown the case where Det(P,x) evaluates to false, but you forgot to mention what happens if Det(P,x) evaluates to true (this case is needed for completeness). For example:

Assume Det(P,x) is true. Then, Det has determined P(x) uses an uninitialized variable with input x. But this is impossible, as P states that if Det(P,x) is true, then we do not use an uninitialized variable.

Now assume Det(P,x) is false. Then, Det has determined P(x) doesn't use an uninitialized variable. But this is impossible, as P states that if Det(P,x) is true, then we use uninitialized variable i.

Thus, evaluating Det(P,x) always results in a contradiction, meaning that it cannot exist.

EDIT: This proof is NOT correct! Observe that Det(P,x) can just inspect P, and if Det(P,x) sees a call to itself, then Det(P,x) chooses to use an uninitialized variable and returns true. Currently trying to find a correct solution (see comments).

Matt Messersmith
  • 12,939
  • 6
  • 51
  • 52
  • Perfect! Thank you. When I say whenever Det(P,x) returns true, its wrong because its impossible, I meant what you wrote in the third paragraph. Yours is a better way of writing it. – a_123 Apr 01 '16 at 02:29
  • @s_123 Glad to help! Proofs are a tricky thing, sometimes the right wording makes all the difference :). You really did have the right idea, my response was just some polishing. Mind accepting the answer if you deem it to be correct? – Matt Messersmith Apr 01 '16 at 02:31
  • I think there's a greyed-out checkmark under the place where you can upvote/downvote. If you click it, it should turn green. – Matt Messersmith Apr 01 '16 at 02:33
  • This isn't a correct proof -- the execution of Det(P, x) may use uninitialized variables and subsequently return true. Or at least, it requires a very careful spelling out of what a "program" is, and what "uses an uninitialized variable" means. – Paul Hankin Apr 01 '16 at 05:30
  • @PaulHankin The point is that regardless of what Det(P,x) evaluates to (it must be true or false), we arrive at a contradiction. I agree that for full correctness more precise definitions are needed, but this proof is correct for any colloquial definition of these concepts. Also, just because the execution of Det(P,x) uses an uninitialized variable does NOT mean that Det(P,x) returns true. It may return true in such a case, but this is not a sufficient condition. Det(P,x) returns true if and only if P uses an uninitialized variable on input x (per definition). – Matt Messersmith Apr 01 '16 at 12:47
  • i think i see what @PaulHankin meant. Det can check if your P looks like this and deliberately use some uninitialized variable and then return true. P will do nothing more in this case, but it already used an uninitialized variable inside Det, so Det returned true correctly. in fact, Det can just check if P calls Det at all, and if so, use an uninitialized variable and return true. – Anton Knyazyev Apr 01 '16 at 13:38
  • i think the proof is supposed to be built around the fact there's no way to implement Det without it trying to run/emulate P(x) in a controlled environment, and since P can potentially run indefinitely, there's no way of telling whether it'll use an uninitialized variable at some point – Anton Knyazyev Apr 01 '16 at 13:52
  • @AntonKnyazyev Nice catch! You're absolutely correct, this proof is wrong. So, you suggest taking the classic "reduction by halting problem" approach? – Matt Messersmith Apr 01 '16 at 23:48
  • You have to be a bit careful. You might try: `Halts(f, x) = Det((lambda x: f(x); var i; print i), x)` to create a program that solves the halting problem, but it has the same problem as before -- in general, f(x) may use undefined variables. But this approach works if you restrict f to a subset of your programming language which can be proven to initialize its variables, and then show that this subset is still Turing powerful. – Paul Hankin Apr 02 '16 at 00:35
  • There's a small loophope there that if f(x) is known to be initialization-safe, then Det can "realize" that and just return false. A modification of the approach would be to take any provable undecidable problem (i.e. one that can either answer "yes" or run forever) and wrap it in such a way that if the answer is "yes" it deliberately uses an uninitialized variable. Yes, the problem must be restricted to those that don't have uninitialized variables themselves (a Turing machine is one I think?). Then there's no way to implement Det for it. – Anton Knyazyev Apr 02 '16 at 18:13